LCOV - code coverage report
Current view: top level - gcc - expr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 80.4 % 6908 5556
Test Date: 2026-02-28 14:20:25 Functions: 93.9 % 180 169
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Convert tree expression to rtl instructions, for GNU compiler.
       2              :    Copyright (C) 1988-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "target.h"
      25              : #include "rtl.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "predict.h"
      29              : #include "memmodel.h"
      30              : #include "tm_p.h"
      31              : #include "ssa.h"
      32              : #include "optabs.h"
      33              : #include "expmed.h"
      34              : #include "regs.h"
      35              : #include "emit-rtl.h"
      36              : #include "recog.h"
      37              : #include "cgraph.h"
      38              : #include "diagnostic.h"
      39              : #include "alias.h"
      40              : #include "fold-const.h"
      41              : #include "stor-layout.h"
      42              : #include "attribs.h"
      43              : #include "varasm.h"
      44              : #include "except.h"
      45              : #include "insn-attr.h"
      46              : #include "dojump.h"
      47              : #include "explow.h"
      48              : #include "calls.h"
      49              : #include "stmt.h"
      50              : /* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
      51              : #include "expr.h"
      52              : #include "optabs-tree.h"
      53              : #include "libfuncs.h"
      54              : #include "reload.h"
      55              : #include "langhooks.h"
      56              : #include "common/common-target.h"
      57              : #include "tree-dfa.h"
      58              : #include "tree-ssa-live.h"
      59              : #include "tree-outof-ssa.h"
      60              : #include "tree-ssa-address.h"
      61              : #include "builtins.h"
      62              : #include "ccmp.h"
      63              : #include "gimple-iterator.h"
      64              : #include "gimple-fold.h"
      65              : #include "rtx-vector-builder.h"
      66              : #include "tree-pretty-print.h"
      67              : #include "flags.h"
      68              : #include "internal-fn.h"
      69              : 
      70              : 
      71              : /* If this is nonzero, we do not bother generating VOLATILE
      72              :    around volatile memory references, and we are willing to
      73              :    output indirect addresses.  If cse is to follow, we reject
      74              :    indirect addresses so a useful potential cse is generated;
      75              :    if it is used only once, instruction combination will produce
      76              :    the same indirect address eventually.  */
      77              : int cse_not_expected;
      78              : 
      79              : /* Cache of the "extended" flag in the target's _BitInt description
      80              :    for use during expand.  */
      81              : int bitint_extended = -1;
      82              : 
      83              : static bool block_move_libcall_safe_for_call_parm (void);
      84              : static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
      85              :                                          HOST_WIDE_INT, unsigned HOST_WIDE_INT,
      86              :                                          unsigned HOST_WIDE_INT,
      87              :                                          unsigned HOST_WIDE_INT, bool);
      88              : static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned, int);
      89              : static void emit_block_move_via_sized_loop (rtx, rtx, rtx, unsigned, unsigned);
      90              : static void emit_block_move_via_oriented_loop (rtx, rtx, rtx, unsigned, unsigned);
      91              : static rtx emit_block_cmp_via_loop (rtx, rtx, rtx, tree, rtx, bool,
      92              :                                     unsigned, unsigned);
      93              : static rtx_insn *compress_float_constant (rtx, rtx);
      94              : static rtx get_subtarget (rtx);
      95              : static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
      96              :                         machine_mode, tree, alias_set_type, bool, bool);
      97              : 
      98              : static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
      99              : 
     100              : static bool is_aligning_offset (const_tree, const_tree);
     101              : static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
     102              : static rtx do_store_flag (const_sepops, rtx, machine_mode);
     103              : #ifdef PUSH_ROUNDING
     104              : static void emit_single_push_insn (machine_mode, rtx, tree);
     105              : #endif
     106              : static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
     107              :                           profile_probability);
     108              : static rtx const_vector_from_tree (tree);
     109              : static tree tree_expr_size (const_tree);
     110              : static void convert_mode_scalar (rtx, rtx, int);
     111              : 
     112              : 
     113              : /* This is run to set up which modes can be used
     114              :    directly in memory and to initialize the block move optab.  It is run
     115              :    at the beginning of compilation and when the target is reinitialized.  */
     116              : 
     117              : void
     118       213440 : init_expr_target (void)
     119              : {
     120       213440 :   rtx pat;
     121       213440 :   int num_clobbers;
     122       213440 :   rtx mem, mem1;
     123       213440 :   rtx reg;
     124              : 
     125              :   /* Try indexing by frame ptr and try by stack ptr.
     126              :      It is known that on the Convex the stack ptr isn't a valid index.
     127              :      With luck, one or the other is valid on any machine.  */
     128       213440 :   mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
     129       213440 :   mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
     130              : 
     131              :   /* A scratch register we can modify in-place below to avoid
     132              :      useless RTL allocations.  */
     133       213440 :   reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
     134              : 
     135       213440 :   rtx_insn *insn = as_a<rtx_insn *> (rtx_alloc (INSN));
     136       213440 :   pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
     137       213440 :   PATTERN (insn) = pat;
     138              : 
     139     26680000 :   for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
     140     26466560 :        mode = (machine_mode) ((int) mode + 1))
     141              :     {
     142     26466560 :       int regno;
     143              : 
     144     26466560 :       direct_load[(int) mode] = direct_store[(int) mode] = 0;
     145     26466560 :       PUT_MODE (mem, mode);
     146     26466560 :       PUT_MODE (mem1, mode);
     147              : 
     148              :       /* See if there is some register that can be used in this mode and
     149              :          directly loaded or stored from memory.  */
     150              : 
     151     26466560 :       if (mode != VOIDmode && mode != BLKmode)
     152   1783862496 :         for (regno = 0; regno < FIRST_PSEUDO_REGISTER
     153   1809902176 :              && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
     154              :              regno++)
     155              :           {
     156   1783862496 :             if (!targetm.hard_regno_mode_ok (regno, mode))
     157   1667052614 :               continue;
     158              : 
     159    116809882 :             set_mode_and_regno (reg, mode, regno);
     160              : 
     161    116809882 :             SET_SRC (pat) = mem;
     162    116809882 :             SET_DEST (pat) = reg;
     163    116809882 :             if (recog (pat, insn, &num_clobbers) >= 0)
     164      7178076 :               direct_load[(int) mode] = 1;
     165              : 
     166    116809882 :             SET_SRC (pat) = mem1;
     167    116809882 :             SET_DEST (pat) = reg;
     168    116809882 :             if (recog (pat, insn, &num_clobbers) >= 0)
     169      7178076 :               direct_load[(int) mode] = 1;
     170              : 
     171    116809882 :             SET_SRC (pat) = reg;
     172    116809882 :             SET_DEST (pat) = mem;
     173    116809882 :             if (recog (pat, insn, &num_clobbers) >= 0)
     174      7178076 :               direct_store[(int) mode] = 1;
     175              : 
     176    116809882 :             SET_SRC (pat) = reg;
     177    116809882 :             SET_DEST (pat) = mem1;
     178    116809882 :             if (recog (pat, insn, &num_clobbers) >= 0)
     179      7178076 :               direct_store[(int) mode] = 1;
     180              :           }
     181              :     }
     182              : 
     183       219144 :   mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
     184              : 
     185       213440 :   opt_scalar_float_mode mode_iter;
     186      1494080 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
     187              :     {
     188      1280640 :       scalar_float_mode mode = mode_iter.require ();
     189      1280640 :       scalar_float_mode srcmode;
     190      4482240 :       FOR_EACH_MODE_UNTIL (srcmode, mode)
     191              :         {
     192      3201600 :           enum insn_code ic;
     193              : 
     194      3201600 :           ic = can_extend_p (mode, srcmode, 0);
     195      3201600 :           if (ic == CODE_FOR_nothing)
     196      2556701 :             continue;
     197              : 
     198       644899 :           PUT_MODE (mem, srcmode);
     199              : 
     200       644899 :           if (insn_operand_matches (ic, 1, mem))
     201       642790 :             float_extend_from_mem[mode][srcmode] = true;
     202              :         }
     203              :     }
     204       213440 : }
     205              : 
     206              : /* This is run at the start of compiling a function.  */
     207              : 
     208              : void
     209      1691107 : init_expr (void)
     210              : {
     211      1691107 :   memset (&crtl->expr, 0, sizeof (crtl->expr));
     212      1691107 : }
     213              : 
     214              : /* Copy data from FROM to TO, where the machine modes are not the same.
     215              :    Both modes may be integer, or both may be floating, or both may be
     216              :    fixed-point.
     217              :    UNSIGNEDP should be nonzero if FROM is an unsigned type.
     218              :    This causes zero-extension instead of sign-extension.  */
     219              : 
     220              : void
     221      2159181 : convert_move (rtx to, rtx from, int unsignedp)
     222              : {
     223      2159181 :   machine_mode to_mode = GET_MODE (to);
     224      2159181 :   machine_mode from_mode = GET_MODE (from);
     225              : 
     226      2159181 :   gcc_assert (to_mode != BLKmode);
     227      2159181 :   gcc_assert (from_mode != BLKmode);
     228              : 
     229              :   /* If the source and destination are already the same, then there's
     230              :      nothing to do.  */
     231      2159181 :   if (to == from)
     232      2159181 :     return;
     233              : 
     234              :   /* If FROM is a SUBREG that indicates that we have already done at least
     235              :      the required extension, strip it.  We don't handle such SUBREGs as
     236              :      TO here.  */
     237              : 
     238      2159181 :   scalar_int_mode to_int_mode;
     239      2159181 :   if (GET_CODE (from) == SUBREG
     240       114277 :       && SUBREG_PROMOTED_VAR_P (from)
     241      2159181 :       && is_a <scalar_int_mode> (to_mode, &to_int_mode)
     242      2159181 :       && (GET_MODE_PRECISION (subreg_promoted_mode (from))
     243            0 :           >= GET_MODE_PRECISION (to_int_mode))
     244      2159181 :       && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
     245              :     {
     246            0 :       scalar_int_mode int_orig_mode;
     247            0 :       scalar_int_mode int_inner_mode;
     248            0 :       machine_mode orig_mode = GET_MODE (from);
     249              : 
     250            0 :       from = gen_lowpart (to_int_mode, SUBREG_REG (from));
     251            0 :       from_mode = to_int_mode;
     252              : 
     253              :       /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
     254              :          the original mode, but narrower than the inner mode.  */
     255            0 :       if (GET_CODE (from) == SUBREG
     256            0 :           && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
     257            0 :           && GET_MODE_PRECISION (to_int_mode)
     258            0 :              > GET_MODE_PRECISION (int_orig_mode)
     259            0 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
     260              :                                      &int_inner_mode)
     261            0 :           && GET_MODE_PRECISION (int_inner_mode)
     262            0 :              > GET_MODE_PRECISION (to_int_mode))
     263              :         {
     264            0 :           SUBREG_PROMOTED_VAR_P (from) = 1;
     265            0 :           SUBREG_PROMOTED_SET (from, unsignedp);
     266              :         }
     267              :     }
     268              : 
     269      2159181 :   gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
     270              : 
     271      2159181 :   if (to_mode == from_mode
     272      2110457 :       || (from_mode == VOIDmode && CONSTANT_P (from)))
     273              :     {
     274        48997 :       emit_move_insn (to, from);
     275        48997 :       return;
     276              :     }
     277              : 
     278      2110184 :   if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
     279              :     {
     280        27806 :       if (GET_MODE_UNIT_PRECISION (to_mode)
     281        13903 :           > GET_MODE_UNIT_PRECISION (from_mode))
     282              :         {
     283         5415 :           optab op = unsignedp ? zext_optab : sext_optab;
     284         5415 :           insn_code icode = convert_optab_handler (op, to_mode, from_mode);
     285         5415 :           if (icode != CODE_FOR_nothing)
     286              :             {
     287          577 :               emit_unop_insn (icode, to, from,
     288              :                               unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
     289          577 :               return;
     290              :             }
     291              :         }
     292              : 
     293        26652 :       if (GET_MODE_UNIT_PRECISION (to_mode)
     294        13326 :           < GET_MODE_UNIT_PRECISION (from_mode))
     295              :         {
     296         1739 :           insn_code icode = convert_optab_handler (trunc_optab,
     297              :                                                    to_mode, from_mode);
     298         1739 :           if (icode != CODE_FOR_nothing)
     299              :             {
     300          862 :               emit_unop_insn (icode, to, from, TRUNCATE);
     301          862 :               return;
     302              :             }
     303              :         }
     304              : 
     305        37392 :       gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
     306              :                             GET_MODE_BITSIZE (to_mode)));
     307              : 
     308        12464 :       if (VECTOR_MODE_P (to_mode))
     309        12464 :         from = force_subreg (to_mode, from, GET_MODE (from), 0);
     310              :       else
     311            0 :         to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
     312              : 
     313        12464 :       emit_move_insn (to, from);
     314        12464 :       return;
     315              :     }
     316              : 
     317      2096281 :   if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
     318              :     {
     319            0 :       convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
     320            0 :       convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
     321            0 :       return;
     322              :     }
     323              : 
     324      2096281 :   convert_mode_scalar (to, from, unsignedp);
     325              : }
     326              : 
     327              : /* Like convert_move, but deals only with scalar modes.  */
     328              : 
     329              : static void
     330      2096331 : convert_mode_scalar (rtx to, rtx from, int unsignedp)
     331              : {
     332              :   /* Both modes should be scalar types.  */
     333      2096336 :   scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
     334      2096336 :   scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
     335      2096336 :   bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
     336      2096336 :   bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
     337      2096336 :   enum insn_code code;
     338      2096336 :   rtx libcall;
     339              : 
     340      2096336 :   gcc_assert (to_real == from_real);
     341              : 
     342              :   /* rtx code for making an equivalent value.  */
     343      3238083 :   enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
     344      2096336 :                               : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
     345              : 
     346      2096336 :   auto acceptable_same_precision_modes
     347          580 :     = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
     348              :     {
     349          580 :       if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
     350              :         return true;
     351              : 
     352              :       /* arm_bfloat_half_format <-> ieee_half_format */
     353            2 :       if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
     354            1 :            && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
     355            2 :           || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     356            1 :               && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
     357              :         return true;
     358              : 
     359              :       /* ibm_extended_format <-> ieee_quad_format */
     360            0 :       if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
     361            0 :            && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
     362            0 :           || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
     363            0 :               && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
     364            0 :         return true;
     365              : 
     366              :       return false;
     367              :     };
     368              : 
     369      2096336 :   if (to_real)
     370              :     {
     371       183087 :       rtx value;
     372       183087 :       rtx_insn *insns;
     373       183087 :       convert_optab tab;
     374              : 
     375       183087 :       gcc_assert ((GET_MODE_PRECISION (from_mode)
     376              :                    != GET_MODE_PRECISION (to_mode))
     377              :                   || acceptable_same_precision_modes (from_mode, to_mode));
     378              : 
     379       183087 :       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
     380              :         {
     381          580 :           if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     382            1 :                && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
     383          580 :               || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
     384            0 :                   && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
     385              :             /* libgcc implements just __trunchfbf2, not __extendhfbf2;
     386              :                and __trunctfkf2, not __extendtfkf2.  */
     387              :             tab = trunc_optab;
     388              :           else
     389              :             /* Conversion between decimal float and binary float, same
     390              :                size.  */
     391          579 :             tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
     392              :         }
     393       182507 :       else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
     394              :         tab = sext_optab;
     395              :       else
     396        18319 :         tab = trunc_optab;
     397              : 
     398              :       /* Try converting directly if the insn is supported.  */
     399              : 
     400       183087 :       code = convert_optab_handler (tab, to_mode, from_mode);
     401       183087 :       if (code != CODE_FOR_nothing)
     402              :         {
     403       160916 :           emit_unop_insn (code, to, from,
     404              :                           tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
     405       160916 :           return;
     406              :         }
     407              : 
     408              : #ifdef HAVE_SFmode
     409        22171 :       if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
     410        22171 :           && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
     411              :         {
     412         2415 :           if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
     413              :             {
     414              :               /* To cut down on libgcc size, implement
     415              :                  BFmode -> {DF,XF,TF}mode conversions by
     416              :                  BFmode -> SFmode -> {DF,XF,TF}mode conversions.  */
     417            4 :               rtx temp = gen_reg_rtx (SFmode);
     418            4 :               convert_mode_scalar (temp, from, unsignedp);
     419            4 :               convert_mode_scalar (to, temp, unsignedp);
     420            4 :               return;
     421              :             }
     422         2411 :           if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
     423              :             {
     424              :               /* Similarly, implement BFmode -> HFmode as
     425              :                  BFmode -> SFmode -> HFmode conversion where SFmode
     426              :                  has superset of BFmode values.  We don't need
     427              :                  to handle sNaNs by raising exception and turning
     428              :                  it into qNaN though, as that can be done in the
     429              :                  SFmode -> HFmode conversion too.  */
     430            1 :               rtx temp = gen_reg_rtx (SFmode);
     431            1 :               int save_flag_finite_math_only = flag_finite_math_only;
     432            1 :               flag_finite_math_only = true;
     433            1 :               convert_mode_scalar (temp, from, unsignedp);
     434            1 :               flag_finite_math_only = save_flag_finite_math_only;
     435            1 :               convert_mode_scalar (to, temp, unsignedp);
     436            1 :               return;
     437              :             }
     438         2410 :           if (to_mode == SFmode
     439         2410 :               && !HONOR_NANS (from_mode)
     440           46 :               && !HONOR_NANS (to_mode)
     441         2456 :               && optimize_insn_for_speed_p ())
     442              :             {
     443              :               /* If we don't expect sNaNs, for BFmode -> SFmode we can just
     444              :                  shift the bits up.  */
     445           45 :               machine_mode fromi_mode, toi_mode;
     446           90 :               if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
     447           45 :                                      0).exists (&fromi_mode)
     448           45 :                   && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
     449            0 :                                         0).exists (&toi_mode))
     450              :                 {
     451           45 :                   start_sequence ();
     452           45 :                   rtx fromi = force_lowpart_subreg (fromi_mode, from,
     453              :                                                     from_mode);
     454           45 :                   rtx tof = NULL_RTX;
     455           45 :                   if (fromi)
     456              :                     {
     457           45 :                       rtx toi;
     458           45 :                       if (GET_MODE (fromi) == VOIDmode)
     459            0 :                         toi = simplify_unary_operation (ZERO_EXTEND, toi_mode,
     460              :                                                         fromi, fromi_mode);
     461              :                       else
     462              :                         {
     463           45 :                           toi = gen_reg_rtx (toi_mode);
     464           45 :                           convert_mode_scalar (toi, fromi, 1);
     465              :                         }
     466           45 :                       toi
     467           90 :                         = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
     468           45 :                                               GET_MODE_PRECISION (to_mode)
     469           45 :                                               - GET_MODE_PRECISION (from_mode),
     470              :                                               NULL_RTX, 1);
     471           45 :                       if (toi)
     472              :                         {
     473           45 :                           tof = force_lowpart_subreg (to_mode, toi, toi_mode);
     474           45 :                           if (tof)
     475           45 :                             emit_move_insn (to, tof);
     476              :                         }
     477              :                     }
     478           45 :                   insns = end_sequence ();
     479           45 :                   if (tof)
     480              :                     {
     481           45 :                       emit_insn (insns);
     482           45 :                       return;
     483              :                     }
     484              :                 }
     485              :             }
     486              :         }
     487        22121 :       if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
     488         4034 :           && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     489         1544 :           && !HONOR_NANS (from_mode)
     490            0 :           && !HONOR_NANS (to_mode)
     491            0 :           && !flag_rounding_math
     492        22121 :           && optimize_insn_for_speed_p ())
     493              :         {
     494              :           /* If we don't expect qNaNs nor sNaNs and can assume rounding
     495              :              to nearest, we can expand the conversion inline as
     496              :              (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16.  */
     497            0 :           machine_mode fromi_mode, toi_mode;
     498            0 :           if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
     499            0 :                                  0).exists (&fromi_mode)
     500            0 :               && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
     501            0 :                                     0).exists (&toi_mode))
     502              :             {
     503            0 :               start_sequence ();
     504            0 :               rtx fromi = force_lowpart_subreg (fromi_mode, from, from_mode);
     505            0 :               rtx tof = NULL_RTX;
     506            0 :               do
     507              :                 {
     508            0 :                   if (!fromi)
     509              :                     break;
     510            0 :                   int shift = (GET_MODE_PRECISION (from_mode)
     511            0 :                                - GET_MODE_PRECISION (to_mode));
     512            0 :                   rtx temp1
     513            0 :                     = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
     514              :                                           shift, NULL_RTX, 1);
     515            0 :                   if (!temp1)
     516              :                     break;
     517            0 :                   rtx temp2
     518            0 :                     = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
     519              :                                     NULL_RTX, 1, OPTAB_DIRECT);
     520            0 :                   if (!temp2)
     521              :                     break;
     522            0 :                   rtx temp3
     523            0 :                     = expand_binop (fromi_mode, add_optab, fromi,
     524              :                                     gen_int_mode ((HOST_WIDE_INT_1U
     525            0 :                                                    << (shift - 1)) - 1,
     526              :                                                   fromi_mode), NULL_RTX,
     527              :                                     1, OPTAB_DIRECT);
     528            0 :                   if (!temp3)
     529              :                     break;
     530            0 :                   rtx temp4
     531            0 :                     = expand_binop (fromi_mode, add_optab, temp3, temp2,
     532              :                                     NULL_RTX, 1, OPTAB_DIRECT);
     533            0 :                   if (!temp4)
     534              :                     break;
     535            0 :                   rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
     536              :                                                   temp4, shift, NULL_RTX, 1);
     537            0 :                   if (!temp5)
     538              :                     break;
     539            0 :                   rtx temp6 = force_lowpart_subreg (toi_mode, temp5,
     540              :                                                     fromi_mode);
     541            0 :                   if (!temp6)
     542              :                     break;
     543            0 :                   tof = force_lowpart_subreg (to_mode, temp6, toi_mode);
     544            0 :                   if (tof)
     545            0 :                     emit_move_insn (to, tof);
     546              :                 }
     547              :               while (0);
     548            0 :               insns = end_sequence ();
     549            0 :               if (tof)
     550              :                 {
     551            0 :                   emit_insn (insns);
     552            0 :                   return;
     553              :                 }
     554              :             }
     555              :         }
     556              : #endif
     557              : 
     558              :       /* Otherwise use a libcall.  */
     559        22121 :       libcall = convert_optab_libfunc (tab, to_mode, from_mode);
     560              : 
     561              :       /* Is this conversion implemented yet?  */
     562        22121 :       gcc_assert (libcall);
     563              : 
     564        22121 :       start_sequence ();
     565        22121 :       value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
     566              :                                        from, from_mode);
     567        22121 :       insns = end_sequence ();
     568        22121 :       emit_libcall_block (insns, to, value,
     569         6507 :                           tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
     570              :                                                                        from)
     571        15614 :                           : gen_rtx_FLOAT_EXTEND (to_mode, from));
     572        22121 :       return;
     573              :     }
     574              : 
     575              :   /* Handle pointer conversion.  */                     /* SPEE 900220.  */
     576              :   /* If the target has a converter from FROM_MODE to TO_MODE, use it.  */
     577      1913249 :   {
     578      1913249 :     convert_optab ctab;
     579              : 
     580      1913249 :     if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
     581              :       ctab = trunc_optab;
     582      1725879 :     else if (unsignedp)
     583              :       ctab = zext_optab;
     584              :     else
     585       877667 :       ctab = sext_optab;
     586              : 
     587      1913249 :     if (convert_optab_handler (ctab, to_mode, from_mode)
     588              :         != CODE_FOR_nothing)
     589              :       {
     590      1655461 :         emit_unop_insn (convert_optab_handler (ctab, to_mode, from_mode),
     591              :                         to, from, UNKNOWN);
     592      1655461 :         return;
     593              :       }
     594              :   }
     595              : 
     596              :   /* Targets are expected to provide conversion insns between PxImode and
     597              :      xImode for all MODE_PARTIAL_INT modes they use, but no others.  */
     598       257788 :   if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
     599              :     {
     600            0 :       scalar_int_mode full_mode
     601            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (to_mode)).require ();
     602              : 
     603            0 :       gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
     604              :                   != CODE_FOR_nothing);
     605              : 
     606            0 :       if (full_mode != from_mode)
     607            0 :         from = convert_to_mode (full_mode, from, unsignedp);
     608            0 :       emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, full_mode),
     609              :                       to, from, UNKNOWN);
     610            0 :       return;
     611              :     }
     612       257788 :   if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
     613              :     {
     614            0 :       rtx new_from;
     615            0 :       scalar_int_mode full_mode
     616            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (from_mode)).require ();
     617            0 :       convert_optab ctab = unsignedp ? zext_optab : sext_optab;
     618            0 :       enum insn_code icode;
     619              : 
     620            0 :       icode = convert_optab_handler (ctab, full_mode, from_mode);
     621            0 :       gcc_assert (icode != CODE_FOR_nothing);
     622              : 
     623            0 :       if (to_mode == full_mode)
     624              :         {
     625            0 :           emit_unop_insn (icode, to, from, UNKNOWN);
     626            0 :           return;
     627              :         }
     628              : 
     629            0 :       new_from = gen_reg_rtx (full_mode);
     630            0 :       emit_unop_insn (icode, new_from, from, UNKNOWN);
     631              : 
     632              :       /* else proceed to integer conversions below.  */
     633            0 :       from_mode = full_mode;
     634            0 :       from = new_from;
     635              :     }
     636              : 
     637              :    /* Make sure both are fixed-point modes or both are not.  */
     638       257788 :    gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
     639              :                ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
     640       257788 :    if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
     641              :     {
     642              :       /* If we widen from_mode to to_mode and they are in the same class,
     643              :          we won't saturate the result.
     644              :          Otherwise, always saturate the result to play safe.  */
     645            0 :       if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
     646            0 :           && GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
     647            0 :         expand_fixed_convert (to, from, 0, 0);
     648              :       else
     649            0 :         expand_fixed_convert (to, from, 0, 1);
     650            0 :       return;
     651              :     }
     652              : 
     653              :   /* Now both modes are integers.  */
     654              : 
     655              :   /* Handle expanding beyond a word.  */
     656       257788 :   if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)
     657       260227 :       && GET_MODE_PRECISION (to_mode) > BITS_PER_WORD)
     658              :     {
     659        70418 :       rtx_insn *insns;
     660        70418 :       rtx lowpart;
     661        70418 :       rtx fill_value;
     662        70418 :       rtx lowfrom;
     663        70418 :       int i;
     664        70418 :       scalar_mode lowpart_mode;
     665       140836 :       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
     666              : 
     667              :       /* Try converting directly if the insn is supported.  */
     668        70418 :       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
     669              :           != CODE_FOR_nothing)
     670              :         {
     671              :           /* If FROM is a SUBREG, put it into a register.  Do this
     672              :              so that we always generate the same set of insns for
     673              :              better cse'ing; if an intermediate assignment occurred,
     674              :              we won't be doing the operation directly on the SUBREG.  */
     675            0 :           if (optimize > 0 && GET_CODE (from) == SUBREG)
     676            0 :             from = force_reg (from_mode, from);
     677            0 :           emit_unop_insn (code, to, from, equiv_code);
     678            0 :           return;
     679              :         }
     680              :       /* Next, try converting via full word.  */
     681        70418 :       else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD
     682        70418 :                && ((code = can_extend_p (to_mode, word_mode, unsignedp))
     683              :                    != CODE_FOR_nothing))
     684              :         {
     685        70418 :           rtx word_to = gen_reg_rtx (word_mode);
     686        70418 :           if (REG_P (to))
     687              :             {
     688        70345 :               if (reg_overlap_mentioned_p (to, from))
     689            0 :                 from = force_reg (from_mode, from);
     690        70345 :               emit_clobber (to);
     691              :             }
     692        70418 :           convert_move (word_to, from, unsignedp);
     693        70418 :           emit_unop_insn (code, to, word_to, equiv_code);
     694        70418 :           return;
     695              :         }
     696              : 
     697              :       /* No special multiword conversion insn; do it by hand.  */
     698            0 :       start_sequence ();
     699              : 
     700              :       /* Since we will turn this into a no conflict block, we must ensure
     701              :          the source does not overlap the target so force it into an isolated
     702              :          register when maybe so.  Likewise for any MEM input, since the
     703              :          conversion sequence might require several references to it and we
     704              :          must ensure we're getting the same value every time.  */
     705              : 
     706            0 :       if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
     707            0 :         from = force_reg (from_mode, from);
     708              : 
     709              :       /* Get a copy of FROM widened to a word, if necessary.  */
     710            0 :       if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD)
     711            0 :         lowpart_mode = word_mode;
     712              :       else
     713              :         lowpart_mode = from_mode;
     714              : 
     715            0 :       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
     716              : 
     717            0 :       lowpart = gen_lowpart (lowpart_mode, to);
     718            0 :       emit_move_insn (lowpart, lowfrom);
     719              : 
     720              :       /* Compute the value to put in each remaining word.  */
     721            0 :       if (unsignedp)
     722            0 :         fill_value = const0_rtx;
     723              :       else
     724            0 :         fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
     725              :                                             LT, lowfrom, const0_rtx,
     726              :                                             lowpart_mode, 0, -1);
     727              : 
     728              :       /* Fill the remaining words.  */
     729            0 :       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
     730              :         {
     731            0 :           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
     732            0 :           rtx subword = operand_subword (to, index, 1, to_mode);
     733              : 
     734            0 :           gcc_assert (subword);
     735              : 
     736            0 :           if (fill_value != subword)
     737            0 :             emit_move_insn (subword, fill_value);
     738              :         }
     739              : 
     740            0 :       insns = end_sequence ();
     741              : 
     742            0 :       emit_insn (insns);
     743            0 :       return;
     744              :     }
     745              : 
     746              :   /* Truncating multi-word to a word or less.  */
     747       187370 :   if (GET_MODE_PRECISION (from_mode) > BITS_PER_WORD
     748       187370 :       && GET_MODE_PRECISION (to_mode) <= BITS_PER_WORD)
     749              :     {
     750        69302 :       if (!((MEM_P (from)
     751          547 :              && ! MEM_VOLATILE_P (from)
     752          547 :              && direct_load[(int) to_mode]
     753          547 :              && ! mode_dependent_address_p (XEXP (from, 0),
     754          547 :                                             MEM_ADDR_SPACE (from)))
     755        39136 :             || REG_P (from)
     756              :             || GET_CODE (from) == SUBREG))
     757            0 :         from = force_reg (from_mode, from);
     758        39683 :       convert_move (to, gen_lowpart (word_mode, from), 0);
     759        39683 :       return;
     760              :     }
     761              : 
     762              :   /* Now follow all the conversions between integers
     763              :      no more than a word long.  */
     764              : 
     765              :   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
     766       295374 :   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
     767       147687 :       && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
     768              :     {
     769       159479 :       if (!((MEM_P (from)
     770        13264 :              && ! MEM_VOLATILE_P (from)
     771        13205 :              && direct_load[(int) to_mode]
     772        13205 :              && ! mode_dependent_address_p (XEXP (from, 0),
     773        13205 :                                             MEM_ADDR_SPACE (from)))
     774       134482 :             || REG_P (from)
     775              :             || GET_CODE (from) == SUBREG))
     776          917 :         from = force_reg (from_mode, from);
     777       123607 :       if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
     778       147688 :           && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
     779            0 :         from = copy_to_reg (from);
     780       147687 :       emit_move_insn (to, gen_lowpart (to_mode, from));
     781       147687 :       return;
     782              :     }
     783              : 
     784              :   /* Handle extension.  */
     785            0 :   if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode))
     786              :     {
     787              :       /* Convert directly if that works.  */
     788            0 :       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
     789              :           != CODE_FOR_nothing)
     790              :         {
     791            0 :           emit_unop_insn (code, to, from, equiv_code);
     792            0 :           return;
     793              :         }
     794              :       else
     795              :         {
     796            0 :           rtx tmp;
     797            0 :           int shift_amount;
     798              : 
     799              :           /* Search for a mode to convert via.  */
     800            0 :           opt_scalar_mode intermediate_iter;
     801            0 :           FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
     802              :             {
     803            0 :               scalar_mode intermediate = intermediate_iter.require ();
     804            0 :               if (((can_extend_p (to_mode, intermediate, unsignedp)
     805              :                     != CODE_FOR_nothing)
     806            0 :                    || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
     807            0 :                        && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
     808              :                                                          intermediate)))
     809            0 :                   && (can_extend_p (intermediate, from_mode, unsignedp)
     810              :                       != CODE_FOR_nothing))
     811              :                 {
     812            0 :                   convert_move (to, convert_to_mode (intermediate, from,
     813              :                                                      unsignedp), unsignedp);
     814            0 :                   return;
     815              :                 }
     816              :             }
     817              : 
     818              :           /* No suitable intermediate mode.
     819              :              Generate what we need with shifts.  */
     820            0 :           shift_amount = (GET_MODE_PRECISION (to_mode)
     821            0 :                           - GET_MODE_PRECISION (from_mode));
     822            0 :           from = gen_lowpart (to_mode, force_reg (from_mode, from));
     823            0 :           tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
     824              :                               to, unsignedp);
     825            0 :           tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
     826              :                               to, unsignedp);
     827            0 :           if (tmp != to)
     828            0 :             emit_move_insn (to, tmp);
     829            0 :           return;
     830              :         }
     831              :     }
     832              : 
     833              :   /* Support special truncate insns for certain modes.  */
     834            0 :   if (convert_optab_handler (trunc_optab, to_mode,
     835              :                              from_mode) != CODE_FOR_nothing)
     836              :     {
     837            0 :       emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, from_mode),
     838              :                       to, from, UNKNOWN);
     839            0 :       return;
     840              :     }
     841              : 
     842              :   /* Handle truncation of volatile memrefs, and so on;
     843              :      the things that couldn't be truncated directly,
     844              :      and for which there was no special instruction.
     845              : 
     846              :      ??? Code above formerly short-circuited this, for most integer
     847              :      mode pairs, with a force_reg in from_mode followed by a recursive
     848              :      call to this routine.  Appears always to have been wrong.  */
     849            0 :   if (GET_MODE_PRECISION (to_mode) < GET_MODE_PRECISION (from_mode))
     850              :     {
     851            0 :       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
     852            0 :       emit_move_insn (to, temp);
     853            0 :       return;
     854              :     }
     855              : 
     856              :   /* Mode combination is not recognized.  */
     857            0 :   gcc_unreachable ();
     858              : }
     859              : 
     860              : /* Return an rtx for a value that would result
     861              :    from converting X to mode MODE.
     862              :    Both X and MODE may be floating, or both integer.
     863              :    UNSIGNEDP is nonzero if X is an unsigned value.
     864              :    This can be done by referring to a part of X in place
     865              :    or by copying to a new temporary with conversion.  */
     866              : 
     867              : rtx
     868      1940274 : convert_to_mode (machine_mode mode, rtx x, int unsignedp)
     869              : {
     870      1940274 :   return convert_modes (mode, VOIDmode, x, unsignedp);
     871              : }
     872              : 
     873              : /* Return an rtx for a value that would result
     874              :    from converting X from mode OLDMODE to mode MODE.
     875              :    Both modes may be floating, or both integer.
     876              :    UNSIGNEDP is nonzero if X is an unsigned value.
     877              : 
     878              :    This can be done by referring to a part of X in place
     879              :    or by copying to a new temporary with conversion.
     880              : 
     881              :    You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.  */
     882              : 
     883              : rtx
     884      4750089 : convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
     885              : {
     886      4750089 :   rtx temp;
     887      4750089 :   scalar_int_mode int_mode;
     888              : 
     889              :   /* If FROM is a SUBREG that indicates that we have already done at least
     890              :      the required extension, strip it.  */
     891              : 
     892      4750089 :   if (GET_CODE (x) == SUBREG
     893        81835 :       && SUBREG_PROMOTED_VAR_P (x)
     894      4750089 :       && is_a <scalar_int_mode> (mode, &int_mode)
     895      4750089 :       && (GET_MODE_PRECISION (subreg_promoted_mode (x))
     896            7 :           >= GET_MODE_PRECISION (int_mode))
     897      4750096 :       && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
     898              :     {
     899            7 :       scalar_int_mode int_orig_mode;
     900            7 :       scalar_int_mode int_inner_mode;
     901            7 :       machine_mode orig_mode = GET_MODE (x);
     902            7 :       x = gen_lowpart (int_mode, SUBREG_REG (x));
     903              : 
     904              :       /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
     905              :          the original mode, but narrower than the inner mode.  */
     906            7 :       if (GET_CODE (x) == SUBREG
     907            0 :           && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
     908            0 :           && GET_MODE_PRECISION (int_mode)
     909            0 :              > GET_MODE_PRECISION (int_orig_mode)
     910            0 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
     911              :                                      &int_inner_mode)
     912            7 :           && GET_MODE_PRECISION (int_inner_mode)
     913            0 :              > GET_MODE_PRECISION (int_mode))
     914              :         {
     915            0 :           SUBREG_PROMOTED_VAR_P (x) = 1;
     916            0 :           SUBREG_PROMOTED_SET (x, unsignedp);
     917              :         }
     918              :     }
     919              : 
     920      4750089 :   if (GET_MODE (x) != VOIDmode)
     921      2480404 :     oldmode = GET_MODE (x);
     922              : 
     923      4750089 :   if (mode == oldmode)
     924              :     return x;
     925              : 
     926      3701190 :   if (CONST_SCALAR_INT_P (x)
     927      3701190 :       && is_a <scalar_int_mode> (mode, &int_mode))
     928              :     {
     929              :       /* If the caller did not tell us the old mode, then there is not
     930              :          much to do with respect to canonicalization.  We have to
     931              :          assume that all the bits are significant.  */
     932      1948560 :       if (!is_a <scalar_int_mode> (oldmode))
     933      1638797 :         oldmode = MAX_MODE_INT;
     934      1948560 :       wide_int w = wide_int::from (rtx_mode_t (x, oldmode),
     935      1948560 :                                    GET_MODE_PRECISION (int_mode),
     936      2798803 :                                    unsignedp ? UNSIGNED : SIGNED);
     937      1948560 :       return immed_wide_int_const (w, int_mode);
     938      1948560 :     }
     939              : 
     940              :   /* We can do this with a gen_lowpart if both desired and current modes
     941              :      are integer, and this is either a constant integer, a register, or a
     942              :      non-volatile MEM. */
     943      1752630 :   scalar_int_mode int_oldmode;
     944      1752630 :   if (is_int_mode (mode, &int_mode)
     945      1661668 :       && is_int_mode (oldmode, &int_oldmode)
     946      1661668 :       && GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (int_oldmode)
     947       438261 :       && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
     948        11768 :           || CONST_POLY_INT_P (x)
     949       426493 :           || (REG_P (x)
     950       390888 :               && (!HARD_REGISTER_P (x)
     951          997 :                   || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
     952       390888 :               && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
     953       402656 :    return gen_lowpart (int_mode, x);
     954              : 
     955              :   /* Converting from integer constant into mode is always equivalent to an
     956              :      subreg operation.  */
     957      1349974 :   if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
     958              :     {
     959            0 :       gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
     960              :                             GET_MODE_BITSIZE (oldmode)));
     961            0 :       return force_subreg (mode, x, oldmode, 0);
     962              :     }
     963              : 
     964      1349974 :   temp = gen_reg_rtx (mode);
     965      1349974 :   convert_move (temp, x, unsignedp);
     966      1349974 :   return temp;
     967              : }
     968              : 
     969              : /* Variant of convert_modes for ABI parameter passing/return.
     970              :    Return an rtx for a value that would result from converting X from
     971              :    a floating point mode FMODE to wider integer mode MODE.  */
     972              : 
     973              : rtx
     974            0 : convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
     975              : {
     976            0 :   gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
     977            0 :   scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
     978            0 :   rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
     979            0 :   return convert_modes (mode, tmp_mode, tmp, 1);
     980              : }
     981              : 
     982              : /* Variant of convert_modes for ABI parameter passing/return.
     983              :    Return an rtx for a value that would result from converting X from
     984              :    an integer mode IMODE to a narrower floating point mode MODE.  */
     985              : 
     986              : rtx
     987            0 : convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
     988              : {
     989            0 :   gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
     990            0 :   scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
     991            0 :   rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
     992            0 :   return gen_lowpart_SUBREG (mode, tmp);
     993              : }
     994              : 
     995              : /* Return the largest alignment we can use for doing a move (or store)
     996              :    of MAX_PIECES.  ALIGN is the largest alignment we could use.  */
     997              : 
     998              : static unsigned int
     999      2726309 : alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
    1000              : {
    1001      2726309 :   scalar_int_mode tmode
    1002      2726309 :     = int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
    1003              : 
    1004      2726309 :   if (align >= GET_MODE_ALIGNMENT (tmode))
    1005      2151589 :     align = GET_MODE_ALIGNMENT (tmode);
    1006              :   else
    1007              :     {
    1008       574720 :       scalar_int_mode xmode = NARROWEST_INT_MODE;
    1009       574720 :       opt_scalar_int_mode mode_iter;
    1010      3464395 :       FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    1011              :         {
    1012      3458735 :           tmode = mode_iter.require ();
    1013      3458735 :           if (GET_MODE_SIZE (tmode) > max_pieces
    1014      3458735 :               || targetm.slow_unaligned_access (tmode, align))
    1015              :             break;
    1016      2889675 :           xmode = tmode;
    1017              :         }
    1018              : 
    1019       574720 :       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
    1020              :     }
    1021              : 
    1022      2726309 :   return align;
    1023              : }
    1024              : 
    1025              : /* Return true if we know how to implement OP using vectors of bytes.  */
    1026              : static bool
    1027      5770892 : can_use_qi_vectors (by_pieces_operation op)
    1028              : {
    1029      5770892 :   return (op == COMPARE_BY_PIECES
    1030            0 :           || op == SET_BY_PIECES
    1031            0 :           || op == CLEAR_BY_PIECES);
    1032              : }
    1033              : 
    1034              : /* Return true if optabs exists for the mode and certain by pieces
    1035              :    operations.  */
    1036              : static bool
    1037     25591247 : by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
    1038              : {
    1039     25591247 :   if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
    1040              :     return false;
    1041              : 
    1042     24315348 :   if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
    1043       634108 :       && VECTOR_MODE_P (mode)
    1044     24770911 :       && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
    1045              :     return false;
    1046              : 
    1047     24267360 :   if (op == COMPARE_BY_PIECES
    1048     24267360 :       && !can_compare_p (EQ, mode, ccp_jump))
    1049              :     return false;
    1050              : 
    1051              :   return true;
    1052              : }
    1053              : 
    1054              : /* Return the widest mode that can be used to perform part of an
    1055              :    operation OP on SIZE bytes.  Try to use QI vector modes where
    1056              :    possible.  */
    1057              : static fixed_size_mode
    1058      5280731 : widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
    1059              : {
    1060      5280731 :   fixed_size_mode result = NARROWEST_INT_MODE;
    1061              : 
    1062      5280731 :   gcc_checking_assert (size > 1);
    1063              : 
    1064              :   /* Use QI vector only if size is wider than a WORD.  */
    1065      5280731 :   if (can_use_qi_vectors (op))
    1066              :     {
    1067       682759 :       machine_mode mode;
    1068       682759 :       fixed_size_mode candidate;
    1069     11292418 :       FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
    1070     11292418 :         if (is_a<fixed_size_mode> (mode, &candidate)
    1071     12387829 :             && GET_MODE_SIZE (candidate) > UNITS_PER_WORD
    1072     12204340 :             && GET_MODE_INNER (candidate) == QImode)
    1073              :           {
    1074      5326822 :             if (GET_MODE_SIZE (candidate) >= size)
    1075              :               break;
    1076      1980652 :             if (by_pieces_mode_supported_p (candidate, op))
    1077     10609659 :               result = candidate;
    1078              :           }
    1079              : 
    1080       682759 :       if (result != NARROWEST_INT_MODE)
    1081       435891 :         return result;
    1082              :     }
    1083              : 
    1084      4844840 :   opt_scalar_int_mode tmode;
    1085      4844840 :   scalar_int_mode mode;
    1086     38758720 :   FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
    1087              :     {
    1088     33913880 :       mode = tmode.require ();
    1089     33913880 :       if (GET_MODE_SIZE (mode) < size
    1090     33913880 :           && by_pieces_mode_supported_p (mode, op))
    1091     23570100 :       result = mode;
    1092              :     }
    1093              : 
    1094      4844840 :   return result;
    1095              : }
    1096              : 
    1097              : /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
    1098              :    and should be performed piecewise.  */
    1099              : 
    1100              : static bool
    1101       954868 : can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
    1102              :                   enum by_pieces_operation op)
    1103              : {
    1104       954868 :   return targetm.use_by_pieces_infrastructure_p (len, align, op,
    1105       954868 :                                                  optimize_insn_for_speed_p ());
    1106              : }
    1107              : 
    1108              : /* Determine whether the LEN bytes can be moved by using several move
    1109              :    instructions.  Return nonzero if a call to move_by_pieces should
    1110              :    succeed.  */
    1111              : 
    1112              : bool
    1113       886474 : can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
    1114              : {
    1115       886474 :   return can_do_by_pieces (len, align, MOVE_BY_PIECES);
    1116              : }
    1117              : 
    1118              : /* Return number of insns required to perform operation OP by pieces
    1119              :    for L bytes.  ALIGN (in bits) is maximum alignment we can assume.  */
    1120              : 
    1121              : unsigned HOST_WIDE_INT
    1122      1925679 : by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
    1123              :                   unsigned int max_size, by_pieces_operation op)
    1124              : {
    1125      1925679 :   unsigned HOST_WIDE_INT n_insns = 0;
    1126      1925679 :   fixed_size_mode mode;
    1127              : 
    1128      1925679 :   if (targetm.overlap_op_by_pieces_p ())
    1129              :     {
    1130              :       /* NB: Round up L and ALIGN to the widest integer mode for
    1131              :          MAX_SIZE.  */
    1132      1925679 :       mode = widest_fixed_size_mode_for_size (max_size, op);
    1133      1925679 :       gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
    1134      3851358 :       unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
    1135      1925679 :       if (up > l)
    1136              :         l = up;
    1137      1925679 :       align = GET_MODE_ALIGNMENT (mode);
    1138              :     }
    1139              : 
    1140      1925679 :   align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
    1141              : 
    1142      5782084 :   while (max_size > 1 && l > 0)
    1143              :     {
    1144      1930726 :       mode = widest_fixed_size_mode_for_size (max_size, op);
    1145      1930726 :       gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
    1146              : 
    1147      1930726 :       unsigned int modesize = GET_MODE_SIZE (mode);
    1148              : 
    1149      1930726 :       if (align >= GET_MODE_ALIGNMENT (mode))
    1150              :         {
    1151      1930726 :           unsigned HOST_WIDE_INT n_pieces = l / modesize;
    1152      1930726 :           l %= modesize;
    1153      1930726 :           switch (op)
    1154              :             {
    1155      1862332 :             default:
    1156      1862332 :               n_insns += n_pieces;
    1157      1862332 :               break;
    1158              : 
    1159        68394 :             case COMPARE_BY_PIECES:
    1160        68394 :               int batch = targetm.compare_by_pieces_branch_ratio (mode);
    1161        68394 :               int batch_ops = 4 * batch - 1;
    1162        68394 :               unsigned HOST_WIDE_INT full = n_pieces / batch;
    1163        68394 :               n_insns += full * batch_ops;
    1164        68394 :               if (n_pieces % batch != 0)
    1165            0 :                 n_insns++;
    1166              :               break;
    1167              : 
    1168              :             }
    1169              :         }
    1170              :       max_size = modesize;
    1171              :     }
    1172              : 
    1173      1925679 :   gcc_assert (!l);
    1174      1925679 :   return n_insns;
    1175              : }
    1176              : 
    1177              : /* Used when performing piecewise block operations, holds information
    1178              :    about one of the memory objects involved.  The member functions
    1179              :    can be used to generate code for loading from the object and
    1180              :    updating the address when iterating.  */
    1181              : 
    1182              : class pieces_addr
    1183              : {
    1184              :   /* The object being referenced, a MEM.  Can be NULL_RTX to indicate
    1185              :      stack pushes.  */
    1186              :   rtx m_obj;
    1187              :   /* The address of the object.  Can differ from that seen in the
    1188              :      MEM rtx if we copied the address to a register.  */
    1189              :   rtx m_addr;
    1190              :   /* Nonzero if the address on the object has an autoincrement already,
    1191              :      signifies whether that was an increment or decrement.  */
    1192              :   signed char m_addr_inc;
    1193              :   /* Nonzero if we intend to use autoinc without the address already
    1194              :      having autoinc form.  We will insert add insns around each memory
    1195              :      reference, expecting later passes to form autoinc addressing modes.
    1196              :      The only supported options are predecrement and postincrement.  */
    1197              :   signed char m_explicit_inc;
    1198              :   /* True if we have either of the two possible cases of using
    1199              :      autoincrement.  */
    1200              :   bool m_auto;
    1201              :   /* True if this is an address to be used for load operations rather
    1202              :      than stores.  */
    1203              :   bool m_is_load;
    1204              : 
    1205              :   /* Optionally, a function to obtain constants for any given offset into
    1206              :      the objects, and data associated with it.  */
    1207              :   by_pieces_constfn m_constfn;
    1208              :   void *m_cfndata;
    1209              : public:
    1210              :   pieces_addr (rtx, bool, by_pieces_constfn, void *);
    1211              :   rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
    1212              :   void increment_address (HOST_WIDE_INT);
    1213              :   void maybe_predec (HOST_WIDE_INT);
    1214              :   void maybe_postinc (HOST_WIDE_INT);
    1215              :   void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
    1216       746642 :   int get_addr_inc ()
    1217              :   {
    1218       746642 :     return m_addr_inc;
    1219              :   }
    1220              : };
    1221              : 
    1222              : /* Initialize a pieces_addr structure from an object OBJ.  IS_LOAD is
    1223              :    true if the operation to be performed on this object is a load
    1224              :    rather than a store.  For stores, OBJ can be NULL, in which case we
    1225              :    assume the operation is a stack push.  For loads, the optional
    1226              :    CONSTFN and its associated CFNDATA can be used in place of the
    1227              :    memory load.  */
    1228              : 
    1229      1493284 : pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
    1230      1493284 :                           void *cfndata)
    1231      1493284 :   : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
    1232              : {
    1233      1493284 :   m_addr_inc = 0;
    1234      1493284 :   m_auto = false;
    1235      1493284 :   if (obj)
    1236              :     {
    1237      1374085 :       rtx addr = XEXP (obj, 0);
    1238      1374085 :       rtx_code code = GET_CODE (addr);
    1239      1374085 :       m_addr = addr;
    1240      1374085 :       bool dec = code == PRE_DEC || code == POST_DEC;
    1241      1374085 :       bool inc = code == PRE_INC || code == POST_INC;
    1242      1374085 :       m_auto = inc || dec;
    1243      1374085 :       if (m_auto)
    1244            0 :         m_addr_inc = dec ? -1 : 1;
    1245              : 
    1246              :       /* While we have always looked for these codes here, the code
    1247              :          implementing the memory operation has never handled them.
    1248              :          Support could be added later if necessary or beneficial.  */
    1249      1374085 :       gcc_assert (code != PRE_INC && code != POST_DEC);
    1250              :     }
    1251              :   else
    1252              :     {
    1253       119199 :       m_addr = NULL_RTX;
    1254       119199 :       if (!is_load)
    1255              :         {
    1256           45 :           m_auto = true;
    1257           45 :           if (STACK_GROWS_DOWNWARD)
    1258           45 :             m_addr_inc = -1;
    1259              :           else
    1260              :             m_addr_inc = 1;
    1261              :         }
    1262              :       else
    1263       119154 :         gcc_assert (constfn != NULL);
    1264              :     }
    1265      1493284 :   m_explicit_inc = 0;
    1266      1493284 :   if (constfn)
    1267       144408 :     gcc_assert (is_load);
    1268      1493284 : }
    1269              : 
    1270              : /* Decide whether to use autoinc for an address involved in a memory op.
    1271              :    MODE is the mode of the accesses, REVERSE is true if we've decided to
    1272              :    perform the operation starting from the end, and LEN is the length of
    1273              :    the operation.  Don't override an earlier decision to set m_auto.  */
    1274              : 
    1275              : void
    1276       366040 : pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
    1277              :                              HOST_WIDE_INT len)
    1278              : {
    1279       366040 :   if (m_auto || m_obj == NULL_RTX)
    1280              :     return;
    1281              : 
    1282       337216 :   bool use_predec = (m_is_load
    1283              :                      ? USE_LOAD_PRE_DECREMENT (mode)
    1284              :                      : USE_STORE_PRE_DECREMENT (mode));
    1285       337216 :   bool use_postinc = (m_is_load
    1286              :                       ? USE_LOAD_POST_INCREMENT (mode)
    1287              :                       : USE_STORE_POST_INCREMENT (mode));
    1288       337216 :   machine_mode addr_mode = get_address_mode (m_obj);
    1289              : 
    1290       337216 :   if (use_predec && reverse)
    1291              :     {
    1292              :       m_addr = copy_to_mode_reg (addr_mode,
    1293              :                                  plus_constant (addr_mode,
    1294              :                                                 m_addr, len));
    1295              :       m_auto = true;
    1296              :       m_explicit_inc = -1;
    1297              :     }
    1298       337216 :   else if (use_postinc && !reverse)
    1299              :     {
    1300              :       m_addr = copy_to_mode_reg (addr_mode, m_addr);
    1301              :       m_auto = true;
    1302              :       m_explicit_inc = 1;
    1303              :     }
    1304       337216 :   else if (CONSTANT_P (m_addr))
    1305        70868 :     m_addr = copy_to_mode_reg (addr_mode, m_addr);
    1306              : }
    1307              : 
    1308              : /* Adjust the address to refer to the data at OFFSET in MODE.  If we
    1309              :    are using autoincrement for this address, we don't add the offset,
    1310              :    but we still modify the MEM's properties.  */
    1311              : 
    1312              : rtx
    1313      4071224 : pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
    1314              :                      by_pieces_prev *prev)
    1315              : {
    1316      4071224 :   if (m_constfn)
    1317              :     /* Pass the previous data to m_constfn.  */
    1318       351163 :     return m_constfn (m_cfndata, prev, offset, mode);
    1319      3720061 :   if (m_obj == NULL_RTX)
    1320              :     return NULL_RTX;
    1321      3720014 :   if (m_auto)
    1322            0 :     return adjust_automodify_address (m_obj, mode, m_addr, offset);
    1323              :   else
    1324      3720014 :     return adjust_address (m_obj, mode, offset);
    1325              : }
    1326              : 
    1327              : /* Emit an add instruction to increment the address by SIZE.  */
    1328              : 
    1329              : void
    1330            0 : pieces_addr::increment_address (HOST_WIDE_INT size)
    1331              : {
    1332            0 :   rtx amount = gen_int_mode (size, GET_MODE (m_addr));
    1333            0 :   emit_insn (gen_add2_insn (m_addr, amount));
    1334            0 : }
    1335              : 
    1336              : /* If we are supposed to decrement the address after each access, emit code
    1337              :    to do so now.  Increment by SIZE (which has should have the correct sign
    1338              :    already).  */
    1339              : 
    1340              : void
    1341      4070560 : pieces_addr::maybe_predec (HOST_WIDE_INT size)
    1342              : {
    1343      4070560 :   if (m_explicit_inc >= 0)
    1344      4070560 :     return;
    1345            0 :   gcc_assert (HAVE_PRE_DECREMENT);
    1346              :   increment_address (size);
    1347              : }
    1348              : 
    1349              : /* If we are supposed to decrement the address after each access, emit code
    1350              :    to do so now.  Increment by SIZE.  */
    1351              : 
    1352              : void
    1353      4070583 : pieces_addr::maybe_postinc (HOST_WIDE_INT size)
    1354              : {
    1355      4070583 :   if (m_explicit_inc <= 0)
    1356      4070583 :     return;
    1357            0 :   gcc_assert (HAVE_POST_INCREMENT);
    1358              :   increment_address (size);
    1359              : }
    1360              : 
    1361              : /* This structure is used by do_op_by_pieces to describe the operation
    1362              :    to be performed.  */
    1363              : 
    1364              : class op_by_pieces_d
    1365              : {
    1366              :  private:
    1367              :   fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
    1368              :   fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
    1369              : 
    1370              :  protected:
    1371              :   pieces_addr m_to, m_from;
    1372              :   /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
    1373              :      use it to check the valid mode size.  */
    1374              :   const unsigned HOST_WIDE_INT m_len;
    1375              :   HOST_WIDE_INT m_offset;
    1376              :   unsigned int m_align;
    1377              :   unsigned int m_max_size;
    1378              :   bool m_reverse;
    1379              :   /* True if this is a stack push.  */
    1380              :   bool m_push;
    1381              :   /* True if targetm.overlap_op_by_pieces_p () returns true.  */
    1382              :   bool m_overlap_op_by_pieces;
    1383              :   /* The type of operation that we're performing.  */
    1384              :   by_pieces_operation m_op;
    1385              : 
    1386              :   /* Virtual functions, overriden by derived classes for the specific
    1387              :      operation.  */
    1388              :   virtual void generate (rtx, rtx, machine_mode) = 0;
    1389              :   virtual bool prepare_mode (machine_mode, unsigned int) = 0;
    1390      1138865 :   virtual void finish_mode (machine_mode)
    1391              :   {
    1392      1138865 :   }
    1393              : 
    1394              :  public:
    1395              :   op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
    1396              :                   void *, unsigned HOST_WIDE_INT, unsigned int, bool,
    1397              :                   by_pieces_operation);
    1398              :   void run ();
    1399              : };
    1400              : 
    1401              : /* The constructor for an op_by_pieces_d structure.  We require two
    1402              :    objects named TO and FROM, which are identified as loads or stores
    1403              :    by TO_LOAD and FROM_LOAD.  If FROM is a load, the optional FROM_CFN
    1404              :    and its associated FROM_CFN_DATA can be used to replace loads with
    1405              :    constant values.  MAX_PIECES describes the maximum number of bytes
    1406              :    at a time which can be moved efficiently.  LEN describes the length
    1407              :    of the operation.  */
    1408              : 
    1409       746642 : op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
    1410              :                                 bool to_load, rtx from, bool from_load,
    1411              :                                 by_pieces_constfn from_cfn,
    1412              :                                 void *from_cfn_data,
    1413              :                                 unsigned HOST_WIDE_INT len,
    1414              :                                 unsigned int align, bool push,
    1415       746642 :                                 by_pieces_operation op)
    1416       746642 :   : m_to (to, to_load, NULL, NULL),
    1417       746642 :     m_from (from, from_load, from_cfn, from_cfn_data),
    1418       746642 :     m_len (len), m_max_size (max_pieces + 1),
    1419       746642 :     m_push (push), m_op (op)
    1420              : {
    1421       746642 :   int toi = m_to.get_addr_inc ();
    1422       746642 :   int fromi = m_from.get_addr_inc ();
    1423       746642 :   if (toi >= 0 && fromi >= 0)
    1424       746597 :     m_reverse = false;
    1425           45 :   else if (toi <= 0 && fromi <= 0)
    1426           45 :     m_reverse = true;
    1427              :   else
    1428            0 :     gcc_unreachable ();
    1429              : 
    1430       746642 :   m_offset = m_reverse ? len : 0;
    1431      2748225 :   align = MIN (to ? MEM_ALIGN (to) : align,
    1432              :                from ? MEM_ALIGN (from) : align);
    1433              : 
    1434              :   /* If copying requires more than two move insns,
    1435              :      copy addresses to registers (to make displacements shorter)
    1436              :      and use post-increment if available.  */
    1437       746642 :   if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
    1438              :     {
    1439              :       /* Find the mode of the largest comparison.  */
    1440       183020 :       fixed_size_mode mode
    1441       183020 :         = widest_fixed_size_mode_for_size (m_max_size, m_op);
    1442              : 
    1443       183020 :       m_from.decide_autoinc (mode, m_reverse, len);
    1444       183020 :       m_to.decide_autoinc (mode, m_reverse, len);
    1445              :     }
    1446              : 
    1447       746652 :   align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
    1448       746642 :   m_align = align;
    1449              : 
    1450       746642 :   m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
    1451       746642 : }
    1452              : 
    1453              : /* This function returns the largest usable integer mode for LEN bytes
    1454              :    whose size is no bigger than size of MODE.  */
    1455              : 
    1456              : fixed_size_mode
    1457      1231524 : op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
    1458              : {
    1459      1530531 :   unsigned int size;
    1460      1829538 :   do
    1461              :     {
    1462      1530531 :       size = GET_MODE_SIZE (mode);
    1463      1530531 :       if (len >= size && prepare_mode (mode, m_align))
    1464              :         break;
    1465              :       /* widest_fixed_size_mode_for_size checks SIZE > 1.  */
    1466       299007 :       mode = widest_fixed_size_mode_for_size (size, m_op);
    1467              :     }
    1468              :   while (1);
    1469      1231524 :   return mode;
    1470              : }
    1471              : 
    1472              : /* Return the smallest integer or QI vector mode that is not narrower
    1473              :    than SIZE bytes.  */
    1474              : 
    1475              : fixed_size_mode
    1476       490161 : op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
    1477              : {
    1478              :   /* Use QI vector only for > size of WORD.  */
    1479       502306 :   if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
    1480              :     {
    1481         7778 :       machine_mode mode;
    1482         7778 :       fixed_size_mode candidate;
    1483       105355 :       FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
    1484       105355 :         if (is_a<fixed_size_mode> (mode, &candidate)
    1485       210710 :             && GET_MODE_INNER (candidate) == QImode)
    1486              :           {
    1487              :             /* Don't return a mode wider than M_LEN.  */
    1488        97886 :             if (GET_MODE_SIZE (candidate) > m_len)
    1489              :               break;
    1490              : 
    1491        47121 :             if (GET_MODE_SIZE (candidate) >= size
    1492        47121 :                 && by_pieces_mode_supported_p (candidate, m_op))
    1493         5956 :               return candidate;
    1494              :           }
    1495              :     }
    1496              : 
    1497       484205 :   return smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
    1498              : }
    1499              : 
    1500              : /* This function contains the main loop used for expanding a block
    1501              :    operation.  First move what we can in the largest integer mode,
    1502              :    then go to successively smaller modes.  For every access, call
    1503              :    GENFUN with the two operands and the EXTRA_DATA.  */
    1504              : 
    1505              : void
    1506       746642 : op_by_pieces_d::run ()
    1507              : {
    1508       746642 :   if (m_len == 0)
    1509              :     return;
    1510              : 
    1511       741363 :   unsigned HOST_WIDE_INT length = m_len;
    1512              : 
    1513              :   /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1.  */
    1514       741363 :   fixed_size_mode mode
    1515       741363 :     = widest_fixed_size_mode_for_size (m_max_size, m_op);
    1516       741363 :   mode = get_usable_mode (mode, length);
    1517              : 
    1518       741363 :   by_pieces_prev to_prev = { nullptr, mode };
    1519       741363 :   by_pieces_prev from_prev = { nullptr, mode };
    1520              : 
    1521      1231524 :   do
    1522              :     {
    1523      1231524 :       unsigned int size = GET_MODE_SIZE (mode);
    1524      1231524 :       rtx to1 = NULL_RTX, from1;
    1525              : 
    1526      3266804 :       while (length >= size)
    1527              :         {
    1528      2035280 :           if (m_reverse)
    1529           47 :             m_offset -= size;
    1530              : 
    1531      2035280 :           to1 = m_to.adjust (mode, m_offset, &to_prev);
    1532      2035280 :           to_prev.data = to1;
    1533      2035280 :           to_prev.mode = mode;
    1534      2035280 :           from1 = m_from.adjust (mode, m_offset, &from_prev);
    1535      2035280 :           from_prev.data = from1;
    1536      2035280 :           from_prev.mode = mode;
    1537              : 
    1538      2035280 :           m_to.maybe_predec (-(HOST_WIDE_INT)size);
    1539      2035280 :           m_from.maybe_predec (-(HOST_WIDE_INT)size);
    1540              : 
    1541      2035280 :           generate (to1, from1, mode);
    1542              : 
    1543      2035280 :           m_to.maybe_postinc (size);
    1544      2035280 :           m_from.maybe_postinc (size);
    1545              : 
    1546      2035280 :           if (!m_reverse)
    1547      2035233 :             m_offset += size;
    1548              : 
    1549      2035280 :           length -= size;
    1550              :         }
    1551              : 
    1552      1231524 :       finish_mode (mode);
    1553              : 
    1554      1231524 :       if (length == 0)
    1555              :         return;
    1556              : 
    1557       490161 :       if (!m_push && m_overlap_op_by_pieces)
    1558              :         {
    1559              :           /* NB: Generate overlapping operations if it is not a stack
    1560              :              push since stack push must not overlap.  Get the smallest
    1561              :              fixed size mode for M_LEN bytes.  */
    1562       490161 :           mode = smallest_fixed_size_mode_for_size (length);
    1563       980322 :           mode = get_usable_mode (mode, GET_MODE_SIZE (mode));
    1564       490161 :           int gap = GET_MODE_SIZE (mode) - length;
    1565       490161 :           if (gap > 0)
    1566              :             {
    1567              :               /* If size of MODE > M_LEN, generate the last operation
    1568              :                  in MODE for the remaining bytes with ovelapping memory
    1569              :                  from the previois operation.  */
    1570        47375 :               if (m_reverse)
    1571            0 :                 m_offset += gap;
    1572              :               else
    1573        47375 :                 m_offset -= gap;
    1574        47375 :               length += gap;
    1575              :             }
    1576              :         }
    1577              :       else
    1578              :         {
    1579              :           /* widest_fixed_size_mode_for_size checks SIZE > 1.  */
    1580            0 :           mode = widest_fixed_size_mode_for_size (size, m_op);
    1581            0 :           mode = get_usable_mode (mode, length);
    1582              :         }
    1583              :     }
    1584              :   while (1);
    1585              : }
    1586              : 
    1587              : /* Derived class from op_by_pieces_d, providing support for block move
    1588              :    operations.  */
    1589              : 
    1590              : #ifdef PUSH_ROUNDING
    1591              : #define PUSHG_P(to)  ((to) == nullptr)
    1592              : #else
    1593              : #define PUSHG_P(to)  false
    1594              : #endif
    1595              : 
    1596              : class move_by_pieces_d : public op_by_pieces_d
    1597              : {
    1598              :   insn_gen_fn m_gen_fun;
    1599              :   void generate (rtx, rtx, machine_mode) final override;
    1600              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1601              : 
    1602              :  public:
    1603       565756 :   move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
    1604              :                     unsigned int align)
    1605       565756 :     : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
    1606      1131512 :                       NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
    1607              :   {
    1608       565756 :   }
    1609              :   rtx finish_retmode (memop_ret);
    1610              : };
    1611              : 
    1612              : /* Return true if MODE can be used for a set of copies, given an
    1613              :    alignment ALIGN.  Prepare whatever data is necessary for later
    1614              :    calls to generate.  */
    1615              : 
    1616              : bool
    1617       947044 : move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1618              : {
    1619       947044 :   insn_code icode = optab_handler (mov_optab, mode);
    1620       947044 :   m_gen_fun = GEN_FCN (icode);
    1621       947044 :   return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
    1622              : }
    1623              : 
    1624              : /* A callback used when iterating for a compare_by_pieces_operation.
    1625              :    OP0 and OP1 are the values that have been loaded and should be
    1626              :    compared in MODE.  If OP0 is NULL, this means we should generate a
    1627              :    push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
    1628              :    gen function that should be used to generate the mode.  */
    1629              : 
    1630              : void
    1631      1638959 : move_by_pieces_d::generate (rtx op0, rtx op1,
    1632              :                             machine_mode mode ATTRIBUTE_UNUSED)
    1633              : {
    1634              : #ifdef PUSH_ROUNDING
    1635      1638959 :   if (op0 == NULL_RTX)
    1636              :     {
    1637           47 :       emit_single_push_insn (mode, op1, NULL);
    1638           47 :       return;
    1639              :     }
    1640              : #endif
    1641      1638912 :   emit_insn (m_gen_fun (op0, op1));
    1642              : }
    1643              : 
    1644              : /* Perform the final adjustment at the end of a string to obtain the
    1645              :    correct return value for the block operation.
    1646              :    Return value is based on RETMODE argument.  */
    1647              : 
    1648              : rtx
    1649            0 : move_by_pieces_d::finish_retmode (memop_ret retmode)
    1650              : {
    1651            0 :   gcc_assert (!m_reverse);
    1652            0 :   if (retmode == RETURN_END_MINUS_ONE)
    1653              :     {
    1654            0 :       m_to.maybe_postinc (-1);
    1655            0 :       --m_offset;
    1656              :     }
    1657            0 :   return m_to.adjust (QImode, m_offset);
    1658              : }
    1659              : 
    1660              : /* Generate several move instructions to copy LEN bytes from block FROM to
    1661              :    block TO.  (These are MEM rtx's with BLKmode).
    1662              : 
    1663              :    If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
    1664              :    used to push FROM to the stack.
    1665              : 
    1666              :    ALIGN is maximum stack alignment we can assume.
    1667              : 
    1668              :    Return value is based on RETMODE argument.  */
    1669              : 
    1670              : rtx
    1671       565756 : move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
    1672              :                 unsigned int align, memop_ret retmode)
    1673              : {
    1674              : #ifndef PUSH_ROUNDING
    1675              :   if (to == NULL)
    1676              :     gcc_unreachable ();
    1677              : #endif
    1678              : 
    1679       565756 :   move_by_pieces_d data (to, from, len, align);
    1680              : 
    1681       565756 :   data.run ();
    1682              : 
    1683       565756 :   if (retmode != RETURN_BEGIN)
    1684            0 :     return data.finish_retmode (retmode);
    1685              :   else
    1686              :     return to;
    1687              : }
    1688              : 
    1689              : /* Derived class from op_by_pieces_d, providing support for block move
    1690              :    operations.  */
    1691              : 
    1692              : class store_by_pieces_d : public op_by_pieces_d
    1693              : {
    1694              :   insn_gen_fn m_gen_fun;
    1695              : 
    1696              :   void generate (rtx, rtx, machine_mode) final override;
    1697              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1698              : 
    1699              :  public:
    1700       119154 :   store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
    1701              :                      unsigned HOST_WIDE_INT len, unsigned int align,
    1702              :                      by_pieces_operation op)
    1703       119154 :     : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
    1704       238308 :                       cfn_data, len, align, false, op)
    1705              :   {
    1706       119154 :   }
    1707              :   rtx finish_retmode (memop_ret);
    1708              : };
    1709              : 
    1710              : /* Return true if MODE can be used for a set of stores, given an
    1711              :    alignment ALIGN.  Prepare whatever data is necessary for later
    1712              :    calls to generate.  */
    1713              : 
    1714              : bool
    1715       191821 : store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1716              : {
    1717       191821 :   insn_code icode = optab_handler (mov_optab, mode);
    1718       191821 :   m_gen_fun = GEN_FCN (icode);
    1719       191821 :   return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
    1720              : }
    1721              : 
    1722              : /* A callback used when iterating for a store_by_pieces_operation.
    1723              :    OP0 and OP1 are the values that have been loaded and should be
    1724              :    compared in MODE.  If OP0 is NULL, this means we should generate a
    1725              :    push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
    1726              :    gen function that should be used to generate the mode.  */
    1727              : 
    1728              : void
    1729       300625 : store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
    1730              : {
    1731       300625 :   emit_insn (m_gen_fun (op0, op1));
    1732       300625 : }
    1733              : 
    1734              : /* Perform the final adjustment at the end of a string to obtain the
    1735              :    correct return value for the block operation.
    1736              :    Return value is based on RETMODE argument.  */
    1737              : 
    1738              : rtx
    1739          664 : store_by_pieces_d::finish_retmode (memop_ret retmode)
    1740              : {
    1741          664 :   gcc_assert (!m_reverse);
    1742          664 :   if (retmode == RETURN_END_MINUS_ONE)
    1743              :     {
    1744           23 :       m_to.maybe_postinc (-1);
    1745           23 :       --m_offset;
    1746              :     }
    1747          664 :   return m_to.adjust (QImode, m_offset);
    1748              : }
    1749              : 
    1750              : /* Determine whether the LEN bytes generated by CONSTFUN can be
    1751              :    stored to memory using several move instructions.  CONSTFUNDATA is
    1752              :    a pointer which will be passed as argument in every CONSTFUN call.
    1753              :    ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
    1754              :    a memset operation and false if it's a copy of a constant string.
    1755              :    Return true if a call to store_by_pieces should succeed.  */
    1756              : 
    1757              : bool
    1758        89205 : can_store_by_pieces (unsigned HOST_WIDE_INT len,
    1759              :                      by_pieces_constfn constfun,
    1760              :                      void *constfundata, unsigned int align, bool memsetp)
    1761              : {
    1762        89205 :   unsigned HOST_WIDE_INT l;
    1763        89205 :   unsigned int max_size;
    1764        89205 :   HOST_WIDE_INT offset = 0;
    1765        89205 :   enum insn_code icode;
    1766        89205 :   int reverse;
    1767              :   /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it.  */
    1768        89205 :   rtx cst ATTRIBUTE_UNUSED;
    1769              : 
    1770        89205 :   if (len == 0)
    1771              :     return true;
    1772              : 
    1773       136835 :   if (!targetm.use_by_pieces_infrastructure_p (len, align,
    1774              :                                                memsetp
    1775              :                                                  ? SET_BY_PIECES
    1776              :                                                  : STORE_BY_PIECES,
    1777        89161 :                                                optimize_insn_for_speed_p ()))
    1778              :     return false;
    1779              : 
    1780        53988 :   align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
    1781              : 
    1782              :   /* We would first store what we can in the largest integer mode, then go to
    1783              :      successively smaller modes.  */
    1784              : 
    1785        53988 :   for (reverse = 0;
    1786       107976 :        reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
    1787              :        reverse++)
    1788              :     {
    1789        53988 :       l = len;
    1790        53988 :       max_size = STORE_MAX_PIECES + 1;
    1791       254924 :       while (max_size > 1 && l > 0)
    1792              :         {
    1793       200936 :           auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
    1794       200936 :           auto mode = widest_fixed_size_mode_for_size (max_size, op);
    1795              : 
    1796       200936 :           icode = optab_handler (mov_optab, mode);
    1797       200936 :           if (icode != CODE_FOR_nothing
    1798       200936 :               && align >= GET_MODE_ALIGNMENT (mode))
    1799              :             {
    1800       200936 :               unsigned int size = GET_MODE_SIZE (mode);
    1801              : 
    1802       343603 :               while (l >= size)
    1803              :                 {
    1804       142667 :                   if (reverse)
    1805              :                     offset -= size;
    1806              : 
    1807       142667 :                   cst = (*constfun) (constfundata, nullptr, offset, mode);
    1808              :                   /* All CONST_VECTORs can be loaded for memset since
    1809              :                      vec_duplicate_optab is a precondition to pick a
    1810              :                      vector mode for the memset expander.  */
    1811       269200 :                   if (!((memsetp && VECTOR_MODE_P (mode))
    1812       126533 :                         || targetm.legitimate_constant_p (mode, cst)))
    1813        35173 :                     return false;
    1814              : 
    1815       142667 :                   if (!reverse)
    1816       142667 :                     offset += size;
    1817              : 
    1818       142667 :                   l -= size;
    1819              :                 }
    1820              :             }
    1821              : 
    1822       401872 :           max_size = GET_MODE_SIZE (mode);
    1823              :         }
    1824              : 
    1825              :       /* The code above should have handled everything.  */
    1826        53988 :       gcc_assert (!l);
    1827              :     }
    1828              : 
    1829              :   return true;
    1830              : }
    1831              : 
    1832              : /* Generate several move instructions to store LEN bytes generated by
    1833              :    CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
    1834              :    pointer which will be passed as argument in every CONSTFUN call.
    1835              :    ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
    1836              :    a memset operation and false if it's a copy of a constant string.
    1837              :    Return value is based on RETMODE argument.  */
    1838              : 
    1839              : rtx
    1840        58390 : store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
    1841              :                  by_pieces_constfn constfun,
    1842              :                  void *constfundata, unsigned int align, bool memsetp,
    1843              :                  memop_ret retmode)
    1844              : {
    1845        58390 :   if (len == 0)
    1846              :     {
    1847         4958 :       gcc_assert (retmode != RETURN_END_MINUS_ONE);
    1848              :       return to;
    1849              :     }
    1850              : 
    1851        97179 :   gcc_assert (targetm.use_by_pieces_infrastructure_p
    1852              :                 (len, align,
    1853              :                  memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
    1854              :                  optimize_insn_for_speed_p ()));
    1855              : 
    1856        53432 :   store_by_pieces_d data (to, constfun, constfundata, len, align,
    1857        53432 :                           memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
    1858        53432 :   data.run ();
    1859              : 
    1860        53432 :   if (retmode != RETURN_BEGIN)
    1861          664 :     return data.finish_retmode (retmode);
    1862              :   else
    1863              :     return to;
    1864              : }
    1865              : 
    1866              : void
    1867        65722 : clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
    1868              : {
    1869        65722 :   if (len == 0)
    1870            0 :     return;
    1871              : 
    1872              :   /* Use builtin_memset_read_str to support vector mode broadcast.  */
    1873        65722 :   char c = 0;
    1874        65722 :   store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
    1875        65722 :                           CLEAR_BY_PIECES);
    1876        65722 :   data.run ();
    1877              : }
    1878              : 
    1879              : /* Context used by compare_by_pieces_genfn.  It stores the fail label
    1880              :    to jump to in case of miscomparison, and for branch ratios greater than 1,
    1881              :    it stores an accumulator and the current and maximum counts before
    1882              :    emitting another branch.  */
    1883              : 
    1884              : class compare_by_pieces_d : public op_by_pieces_d
    1885              : {
    1886              :   rtx_code_label *m_fail_label;
    1887              :   rtx m_accumulator;
    1888              :   int m_count, m_batch;
    1889              : 
    1890              :   void generate (rtx, rtx, machine_mode) final override;
    1891              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1892              :   void finish_mode (machine_mode) final override;
    1893              : 
    1894              :  public:
    1895        61732 :   compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
    1896              :                        void *op1_cfn_data, HOST_WIDE_INT len, int align,
    1897              :                        rtx_code_label *fail_label)
    1898        61732 :     : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
    1899       123464 :                       op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
    1900              :   {
    1901        61732 :     m_fail_label = fail_label;
    1902        61732 :   }
    1903              : };
    1904              : 
    1905              : /* A callback used when iterating for a compare_by_pieces_operation.
    1906              :    OP0 and OP1 are the values that have been loaded and should be
    1907              :    compared in MODE.  DATA holds a pointer to the compare_by_pieces_data
    1908              :    context structure.  */
    1909              : 
    1910              : void
    1911        95696 : compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
    1912              : {
    1913        95696 :   if (m_batch > 1)
    1914              :     {
    1915            0 :       rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
    1916              :                                true, OPTAB_LIB_WIDEN);
    1917            0 :       if (m_count != 0)
    1918            0 :         temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
    1919              :                              true, OPTAB_LIB_WIDEN);
    1920            0 :       m_accumulator = temp;
    1921              : 
    1922            0 :       if (++m_count < m_batch)
    1923              :         return;
    1924              : 
    1925            0 :       m_count = 0;
    1926            0 :       op0 = m_accumulator;
    1927            0 :       op1 = const0_rtx;
    1928            0 :       m_accumulator = NULL_RTX;
    1929              :     }
    1930        95696 :   do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
    1931              :                            m_fail_label, profile_probability::uninitialized ());
    1932              : }
    1933              : 
    1934              : /* Return true if MODE can be used for a set of moves and comparisons,
    1935              :    given an alignment ALIGN.  Prepare whatever data is necessary for
    1936              :    later calls to generate.  */
    1937              : 
    1938              : bool
    1939        92659 : compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1940              : {
    1941        92659 :   insn_code icode = optab_handler (mov_optab, mode);
    1942        92659 :   if (icode == CODE_FOR_nothing
    1943        92659 :       || align < GET_MODE_ALIGNMENT (mode)
    1944       185318 :       || !can_compare_p (EQ, mode, ccp_jump))
    1945            0 :     return false;
    1946        92659 :   m_batch = targetm.compare_by_pieces_branch_ratio (mode);
    1947        92659 :   if (m_batch < 0)
    1948              :     return false;
    1949        92659 :   m_accumulator = NULL_RTX;
    1950        92659 :   m_count = 0;
    1951        92659 :   return true;
    1952              : }
    1953              : 
    1954              : /* Called after expanding a series of comparisons in MODE.  If we have
    1955              :    accumulated results for which we haven't emitted a branch yet, do
    1956              :    so now.  */
    1957              : 
    1958              : void
    1959        92659 : compare_by_pieces_d::finish_mode (machine_mode mode)
    1960              : {
    1961        92659 :   if (m_accumulator != NULL_RTX)
    1962            0 :     do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
    1963              :                              NULL_RTX, NULL, m_fail_label,
    1964              :                              profile_probability::uninitialized ());
    1965        92659 : }
    1966              : 
    1967              : /* Generate several move instructions to compare LEN bytes from blocks
    1968              :    ARG0 and ARG1.  (These are MEM rtx's with BLKmode).
    1969              : 
    1970              :    If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
    1971              :    used to push FROM to the stack.
    1972              : 
    1973              :    ALIGN is maximum stack alignment we can assume.
    1974              : 
    1975              :    Optionally, the caller can pass a constfn and associated data in A1_CFN
    1976              :    and A1_CFN_DATA. describing that the second operand being compared is a
    1977              :    known constant and how to obtain its data.  */
    1978              : 
    1979              : static rtx
    1980        61732 : compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
    1981              :                    rtx target, unsigned int align,
    1982              :                    by_pieces_constfn a1_cfn, void *a1_cfn_data)
    1983              : {
    1984        61732 :   rtx_code_label *fail_label = gen_label_rtx ();
    1985        61732 :   rtx_code_label *end_label = gen_label_rtx ();
    1986              : 
    1987        61732 :   if (target == NULL_RTX
    1988        61732 :       || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
    1989            2 :     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
    1990              : 
    1991        61732 :   compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
    1992        61732 :                             fail_label);
    1993              : 
    1994        61732 :   data.run ();
    1995              : 
    1996        61732 :   emit_move_insn (target, const0_rtx);
    1997        61732 :   emit_jump (end_label);
    1998        61732 :   emit_barrier ();
    1999        61732 :   emit_label (fail_label);
    2000        61732 :   emit_move_insn (target, const1_rtx);
    2001        61732 :   emit_label (end_label);
    2002              : 
    2003        61732 :   return target;
    2004              : }
    2005              : 
    2006              : /* Emit code to move a block Y to a block X.  This may be done with
    2007              :    string-move instructions, with multiple scalar move instructions,
    2008              :    or with a library call.
    2009              : 
    2010              :    Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
    2011              :    SIZE is an rtx that says how long they are.
    2012              :    ALIGN is the maximum alignment we can assume they have.
    2013              :    METHOD describes what kind of copy this is, and what mechanisms may be used.
    2014              :    MIN_SIZE is the minimal size of block to move
    2015              :    MAX_SIZE is the maximal size of block to move, if it cannot be represented
    2016              :    in unsigned HOST_WIDE_INT, than it is mask of all ones.
    2017              :    CTZ_SIZE is the trailing-zeros count of SIZE; even a nonconstant SIZE is
    2018              :    known to be a multiple of 1<<CTZ_SIZE.
    2019              : 
    2020              :    Return the address of the new block, if memcpy is called and returns it,
    2021              :    0 otherwise.  */
    2022              : 
    2023              : rtx
    2024       662333 : emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
    2025              :                        unsigned int expected_align, HOST_WIDE_INT expected_size,
    2026              :                        unsigned HOST_WIDE_INT min_size,
    2027              :                        unsigned HOST_WIDE_INT max_size,
    2028              :                        unsigned HOST_WIDE_INT probable_max_size,
    2029              :                        bool bail_out_libcall, bool *is_move_done,
    2030              :                        bool might_overlap, unsigned ctz_size)
    2031              : {
    2032       662333 :   int may_use_call;
    2033       662333 :   rtx retval = 0;
    2034       662333 :   unsigned int align;
    2035              : 
    2036       662333 :   if (is_move_done)
    2037        94254 :     *is_move_done = true;
    2038              : 
    2039       662333 :   gcc_assert (size);
    2040       662333 :   if (CONST_INT_P (size) && INTVAL (size) == 0)
    2041              :     return 0;
    2042              : 
    2043       662056 :   switch (method)
    2044              :     {
    2045              :     case BLOCK_OP_NORMAL:
    2046              :     case BLOCK_OP_TAILCALL:
    2047              :       may_use_call = 1;
    2048              :       break;
    2049              : 
    2050       268185 :     case BLOCK_OP_CALL_PARM:
    2051       268185 :       may_use_call = block_move_libcall_safe_for_call_parm ();
    2052              : 
    2053              :       /* Make inhibit_defer_pop nonzero around the library call
    2054              :          to force it to pop the arguments right away.  */
    2055       268185 :       NO_DEFER_POP;
    2056       268185 :       break;
    2057              : 
    2058          354 :     case BLOCK_OP_NO_LIBCALL:
    2059          354 :       may_use_call = 0;
    2060          354 :       break;
    2061              : 
    2062         1061 :     case BLOCK_OP_NO_LIBCALL_RET:
    2063         1061 :       may_use_call = -1;
    2064         1061 :       break;
    2065              : 
    2066            0 :     default:
    2067            0 :       gcc_unreachable ();
    2068              :     }
    2069              : 
    2070       662056 :   gcc_assert (MEM_P (x) && MEM_P (y));
    2071       662141 :   align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
    2072       662056 :   gcc_assert (align >= BITS_PER_UNIT);
    2073              : 
    2074              :   /* Make sure we've got BLKmode addresses; store_one_arg can decide that
    2075              :      block copy is more efficient for other large modes, e.g. DCmode.  */
    2076       662056 :   x = adjust_address (x, BLKmode, 0);
    2077       662056 :   y = adjust_address (y, BLKmode, 0);
    2078              : 
    2079              :   /* If source and destination are the same, no need to copy anything.  */
    2080       662056 :   if (rtx_equal_p (x, y)
    2081           13 :       && !MEM_VOLATILE_P (x)
    2082       662069 :       && !MEM_VOLATILE_P (y))
    2083              :     return 0;
    2084              : 
    2085              :   /* Set MEM_SIZE as appropriate for this block copy.  The main place this
    2086              :      can be incorrect is coming from __builtin_memcpy.  */
    2087       662043 :   poly_int64 const_size;
    2088       662043 :   if (poly_int_rtx_p (size, &const_size))
    2089              :     {
    2090       585707 :       x = shallow_copy_rtx (x);
    2091       585707 :       y = shallow_copy_rtx (y);
    2092       585707 :       set_mem_size (x, const_size);
    2093       585707 :       set_mem_size (y, const_size);
    2094              :     }
    2095              : 
    2096       662043 :   bool pieces_ok = CONST_INT_P (size)
    2097       662043 :     && can_move_by_pieces (INTVAL (size), align);
    2098       662043 :   bool pattern_ok = false;
    2099              : 
    2100       662043 :   if (!pieces_ok || might_overlap)
    2101              :     {
    2102       102108 :       pattern_ok
    2103       102108 :         = emit_block_move_via_pattern (x, y, size, align,
    2104              :                                        expected_align, expected_size,
    2105              :                                        min_size, max_size, probable_max_size,
    2106              :                                        might_overlap);
    2107       102108 :       if (!pattern_ok && might_overlap)
    2108              :         {
    2109              :           /* Do not try any of the other methods below as they are not safe
    2110              :              for overlapping moves.  */
    2111        10630 :           *is_move_done = false;
    2112        10630 :           return retval;
    2113              :         }
    2114              :     }
    2115              : 
    2116        91478 :   bool dynamic_direction = false;
    2117        91478 :   if (!pattern_ok && !pieces_ok && may_use_call
    2118       128462 :       && (flag_inline_stringops & (might_overlap ? ILSOP_MEMMOVE : ILSOP_MEMCPY)))
    2119              :     {
    2120       651413 :       may_use_call = 0;
    2121       651413 :       dynamic_direction = might_overlap;
    2122              :     }
    2123              : 
    2124       651413 :   if (pattern_ok)
    2125              :     ;
    2126       624166 :   else if (pieces_ok)
    2127       559935 :     move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
    2128        64231 :   else if (may_use_call && !might_overlap
    2129        64183 :            && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
    2130       128414 :            && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
    2131              :     {
    2132        64183 :       if (bail_out_libcall)
    2133              :         {
    2134          251 :           if (is_move_done)
    2135          251 :             *is_move_done = false;
    2136          251 :           return retval;
    2137              :         }
    2138              : 
    2139        63932 :       if (may_use_call < 0)
    2140            0 :         return pc_rtx;
    2141              : 
    2142        63932 :       retval = emit_block_copy_via_libcall (x, y, size,
    2143              :                                             method == BLOCK_OP_TAILCALL);
    2144              :     }
    2145           48 :   else if (dynamic_direction)
    2146            0 :     emit_block_move_via_oriented_loop (x, y, size, align, ctz_size);
    2147           48 :   else if (might_overlap)
    2148            0 :     *is_move_done = false;
    2149              :   else
    2150           48 :     emit_block_move_via_sized_loop (x, y, size, align, ctz_size);
    2151              : 
    2152       651162 :   if (method == BLOCK_OP_CALL_PARM)
    2153       268174 :     OK_DEFER_POP;
    2154              : 
    2155              :   return retval;
    2156              : }
    2157              : 
    2158              : rtx
    2159       568079 : emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method,
    2160              :                  unsigned int ctz_size)
    2161              : {
    2162       568079 :   unsigned HOST_WIDE_INT max, min = 0;
    2163       568079 :   if (GET_CODE (size) == CONST_INT)
    2164       567859 :     min = max = UINTVAL (size);
    2165              :   else
    2166          220 :     max = GET_MODE_MASK (GET_MODE (size));
    2167       568079 :   return emit_block_move_hints (x, y, size, method, 0, -1,
    2168              :                                 min, max, max,
    2169       568079 :                                 false, NULL, false, ctz_size);
    2170              : }
    2171              : 
    2172              : /* A subroutine of emit_block_move.  Returns true if calling the
    2173              :    block move libcall will not clobber any parameters which may have
    2174              :    already been placed on the stack.  */
    2175              : 
    2176              : static bool
    2177       268185 : block_move_libcall_safe_for_call_parm (void)
    2178              : {
    2179       268185 :   tree fn;
    2180              : 
    2181              :   /* If arguments are pushed on the stack, then they're safe.  */
    2182       268185 :   if (targetm.calls.push_argument (0))
    2183              :     return true;
    2184              : 
    2185              :   /* If registers go on the stack anyway, any argument is sure to clobber
    2186              :      an outgoing argument.  */
    2187              : #if defined (REG_PARM_STACK_SPACE)
    2188            3 :   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    2189              :   /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
    2190              :      depend on its argument.  */
    2191            3 :   (void) fn;
    2192            3 :   if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
    2193            3 :       && REG_PARM_STACK_SPACE (fn) != 0)
    2194              :     return false;
    2195              : #endif
    2196              : 
    2197              :   /* If any argument goes in memory, then it might clobber an outgoing
    2198              :      argument.  */
    2199            3 :   {
    2200            3 :     CUMULATIVE_ARGS args_so_far_v;
    2201            3 :     cumulative_args_t args_so_far;
    2202            3 :     tree arg;
    2203              : 
    2204            3 :     fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    2205            3 :     INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
    2206            3 :     args_so_far = pack_cumulative_args (&args_so_far_v);
    2207              : 
    2208            3 :     arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
    2209           12 :     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
    2210              :       {
    2211            9 :         machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
    2212            9 :         function_arg_info arg_info (mode, /*named=*/true);
    2213            9 :         rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
    2214            9 :         if (!tmp || !REG_P (tmp))
    2215            0 :           return false;
    2216            9 :         if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
    2217              :           return false;
    2218            9 :         targetm.calls.function_arg_advance (args_so_far, arg_info);
    2219              :       }
    2220              :   }
    2221            3 :   return true;
    2222              : }
    2223              : 
    2224              : /* A subroutine of emit_block_move.  Expand a cpymem or movmem pattern;
    2225              :    return true if successful.
    2226              : 
    2227              :    X is the destination of the copy or move.
    2228              :    Y is the source of the copy or move.
    2229              :    SIZE is the size of the block to be moved.
    2230              : 
    2231              :    MIGHT_OVERLAP indicates this originated with expansion of a
    2232              :    builtin_memmove() and the source and destination blocks may
    2233              :    overlap.
    2234              :   */
    2235              : 
    2236              : static bool
    2237       102108 : emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
    2238              :                              unsigned int expected_align,
    2239              :                              HOST_WIDE_INT expected_size,
    2240              :                              unsigned HOST_WIDE_INT min_size,
    2241              :                              unsigned HOST_WIDE_INT max_size,
    2242              :                              unsigned HOST_WIDE_INT probable_max_size,
    2243              :                              bool might_overlap)
    2244              : {
    2245       102108 :   if (expected_align < align)
    2246              :     expected_align = align;
    2247       102108 :   if (expected_size != -1)
    2248              :     {
    2249           13 :       if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
    2250            0 :         expected_size = probable_max_size;
    2251           13 :       if ((unsigned HOST_WIDE_INT)expected_size < min_size)
    2252            0 :         expected_size = min_size;
    2253              :     }
    2254              : 
    2255              :   /* Since this is a move insn, we don't care about volatility.  */
    2256       102108 :   temporary_volatile_ok v (true);
    2257              : 
    2258              :   /* Try the most limited insn first, because there's no point
    2259              :      including more than one in the machine description unless
    2260              :      the more limited one has some advantage.  */
    2261              : 
    2262       102108 :   opt_scalar_int_mode mode_iter;
    2263       684937 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    2264              :     {
    2265       610076 :       scalar_int_mode mode = mode_iter.require ();
    2266       610076 :       enum insn_code code;
    2267       610076 :       if (might_overlap)
    2268        94522 :         code = direct_optab_handler (movmem_optab, mode);
    2269              :       else
    2270       515554 :         code = direct_optab_handler (cpymem_optab, mode);
    2271              : 
    2272       610076 :       if (code != CODE_FOR_nothing
    2273              :           /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
    2274              :              here because if SIZE is less than the mode mask, as it is
    2275              :              returned by the macro, it will definitely be less than the
    2276              :              actual mode mask.  Since SIZE is within the Pmode address
    2277              :              space, we limit MODE to Pmode.  */
    2278       610076 :           && ((CONST_INT_P (size)
    2279        40319 :                && ((unsigned HOST_WIDE_INT) INTVAL (size)
    2280        40319 :                    <= (GET_MODE_MASK (mode) >> 1)))
    2281       136051 :               || max_size <= (GET_MODE_MASK (mode) >> 1)
    2282       169180 :               || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
    2283              :         {
    2284       118413 :           class expand_operand ops[9];
    2285       118413 :           unsigned int nops;
    2286              : 
    2287              :           /* ??? When called via emit_block_move_for_call, it'd be
    2288              :              nice if there were some way to inform the backend, so
    2289              :              that it doesn't fail the expansion because it thinks
    2290              :              emitting the libcall would be more efficient.  */
    2291       118413 :           nops = insn_data[(int) code].n_generator_args;
    2292       118413 :           gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
    2293              : 
    2294       118413 :           create_fixed_operand (&ops[0], x);
    2295       118413 :           create_fixed_operand (&ops[1], y);
    2296              :           /* The check above guarantees that this size conversion is valid.  */
    2297       118413 :           create_convert_operand_to (&ops[2], size, mode, true);
    2298       118413 :           create_integer_operand (&ops[3], align / BITS_PER_UNIT);
    2299       118413 :           if (nops >= 6)
    2300              :             {
    2301       118413 :               create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
    2302       118413 :               create_integer_operand (&ops[5], expected_size);
    2303              :             }
    2304       118413 :           if (nops >= 8)
    2305              :             {
    2306       118413 :               create_integer_operand (&ops[6], min_size);
    2307              :               /* If we cannot represent the maximal size,
    2308              :                  make parameter NULL.  */
    2309       118413 :               if ((HOST_WIDE_INT) max_size != -1)
    2310       102704 :                 create_integer_operand (&ops[7], max_size);
    2311              :               else
    2312        15709 :                 create_fixed_operand (&ops[7], NULL);
    2313              :             }
    2314       118413 :           if (nops == 9)
    2315              :             {
    2316              :               /* If we cannot represent the maximal size,
    2317              :                  make parameter NULL.  */
    2318       118413 :               if ((HOST_WIDE_INT) probable_max_size != -1)
    2319       105165 :                 create_integer_operand (&ops[8], probable_max_size);
    2320              :               else
    2321        13248 :                 create_fixed_operand (&ops[8], NULL);
    2322              :             }
    2323       118413 :           if (maybe_expand_insn (code, nops, ops))
    2324        27247 :             return true;
    2325              :         }
    2326              :     }
    2327              : 
    2328              :   return false;
    2329       102108 : }
    2330              : 
    2331              : /* Like emit_block_move_via_loop, but choose a suitable INCR based on
    2332              :    ALIGN and CTZ_SIZE.  */
    2333              : 
    2334              : static void
    2335           48 : emit_block_move_via_sized_loop (rtx x, rtx y, rtx size,
    2336              :                                 unsigned int align,
    2337              :                                 unsigned int ctz_size)
    2338              : {
    2339           48 :   int incr = align / BITS_PER_UNIT;
    2340              : 
    2341           48 :   if (CONST_INT_P (size))
    2342            0 :     ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
    2343              : 
    2344           48 :   if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
    2345            0 :     incr = HOST_WIDE_INT_1U << ctz_size;
    2346              : 
    2347           48 :   while (incr > 1 && !can_move_by_pieces (incr, align))
    2348            0 :     incr >>= 1;
    2349              : 
    2350           48 :   gcc_checking_assert (incr);
    2351              : 
    2352           48 :   return emit_block_move_via_loop (x, y, size, align, incr);
    2353              : }
    2354              : 
    2355              : /* Like emit_block_move_via_sized_loop, but besides choosing INCR so
    2356              :    as to ensure safe moves even in case of overlap, output dynamic
    2357              :    tests to choose between two loops, one moving downwards, another
    2358              :    moving upwards.  */
    2359              : 
    2360              : static void
    2361            0 : emit_block_move_via_oriented_loop (rtx x, rtx y, rtx size,
    2362              :                                    unsigned int align,
    2363              :                                    unsigned int ctz_size)
    2364              : {
    2365            0 :   int incr = align / BITS_PER_UNIT;
    2366              : 
    2367            0 :   if (CONST_INT_P (size))
    2368            0 :     ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
    2369              : 
    2370            0 :   if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
    2371            0 :     incr = HOST_WIDE_INT_1U << ctz_size;
    2372              : 
    2373            0 :   while (incr > 1 && !int_mode_for_size (incr, 0).exists ())
    2374            0 :     incr >>= 1;
    2375              : 
    2376            0 :   gcc_checking_assert (incr);
    2377              : 
    2378            0 :   rtx_code_label *upw_label, *end_label;
    2379            0 :   upw_label = gen_label_rtx ();
    2380            0 :   end_label = gen_label_rtx ();
    2381              : 
    2382            0 :   rtx x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2383            0 :   rtx y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2384            0 :   do_pending_stack_adjust ();
    2385              : 
    2386            0 :   machine_mode mode = GET_MODE (x_addr);
    2387            0 :   if (mode != GET_MODE (y_addr))
    2388              :     {
    2389            0 :       scalar_int_mode xmode
    2390            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (mode)).require ();
    2391            0 :       scalar_int_mode ymode
    2392            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE
    2393            0 :                                       (GET_MODE (y_addr))).require ();
    2394            0 :       if (GET_MODE_BITSIZE (xmode) < GET_MODE_BITSIZE (ymode))
    2395              :         mode = ymode;
    2396              :       else
    2397            0 :         mode = xmode;
    2398              : 
    2399              : #ifndef POINTERS_EXTEND_UNSIGNED
    2400              :       const int POINTERS_EXTEND_UNSIGNED = 1;
    2401              : #endif
    2402            0 :       x_addr = convert_modes (mode, GET_MODE (x_addr), x_addr,
    2403              :                               POINTERS_EXTEND_UNSIGNED);
    2404            0 :       y_addr = convert_modes (mode, GET_MODE (y_addr), y_addr,
    2405              :                               POINTERS_EXTEND_UNSIGNED);
    2406              :     }
    2407              : 
    2408              :   /* Test for overlap: if (x >= y || x + size <= y) goto upw_label.  */
    2409            0 :   emit_cmp_and_jump_insns (x_addr, y_addr, GEU, NULL_RTX, mode,
    2410              :                            true, upw_label,
    2411            0 :                            profile_probability::guessed_always ()
    2412              :                                 .apply_scale (5, 10));
    2413            0 :   rtx tmp = convert_modes (GET_MODE (x_addr), GET_MODE (size), size, true);
    2414            0 :   tmp = simplify_gen_binary (PLUS, GET_MODE (x_addr), x_addr, tmp);
    2415              : 
    2416            0 :   emit_cmp_and_jump_insns (tmp, y_addr, LEU, NULL_RTX, mode,
    2417              :                            true, upw_label,
    2418            0 :                            profile_probability::guessed_always ()
    2419              :                                 .apply_scale (8, 10));
    2420              : 
    2421            0 :   emit_block_move_via_loop (x, y, size, align, -incr);
    2422              : 
    2423            0 :   emit_jump (end_label);
    2424            0 :   emit_label (upw_label);
    2425              : 
    2426            0 :   emit_block_move_via_loop (x, y, size, align, incr);
    2427              : 
    2428            0 :   emit_label (end_label);
    2429            0 : }
    2430              : 
    2431              : /* A subroutine of emit_block_move.  Copy the data via an explicit
    2432              :    loop.  This is used only when libcalls are forbidden, or when
    2433              :    inlining is required.  INCR is the block size to be copied in each
    2434              :    loop iteration.  If it is negative, the absolute value is used, and
    2435              :    the block is copied backwards.  INCR must be a power of two, an
    2436              :    exact divisor for SIZE and ALIGN, and imply a mode that can be
    2437              :    safely copied per iteration assuming no overlap.  */
    2438              : 
    2439              : static void
    2440           48 : emit_block_move_via_loop (rtx x, rtx y, rtx size,
    2441              :                           unsigned int align, int incr)
    2442              : {
    2443           48 :   rtx_code_label *cmp_label, *top_label;
    2444           48 :   rtx iter, x_addr, y_addr, tmp;
    2445           48 :   machine_mode x_addr_mode = get_address_mode (x);
    2446           48 :   machine_mode y_addr_mode = get_address_mode (y);
    2447           48 :   machine_mode iter_mode;
    2448              : 
    2449           48 :   iter_mode = GET_MODE (size);
    2450           48 :   if (iter_mode == VOIDmode)
    2451            0 :     iter_mode = word_mode;
    2452              : 
    2453           48 :   top_label = gen_label_rtx ();
    2454           48 :   cmp_label = gen_label_rtx ();
    2455           48 :   iter = gen_reg_rtx (iter_mode);
    2456              : 
    2457           48 :   bool downwards = incr < 0;
    2458           48 :   rtx iter_init;
    2459           48 :   rtx_code iter_cond;
    2460           48 :   rtx iter_limit;
    2461           48 :   rtx iter_incr;
    2462           48 :   machine_mode move_mode;
    2463           48 :   if (downwards)
    2464              :     {
    2465            0 :       incr = -incr;
    2466            0 :       iter_init = size;
    2467            0 :       iter_cond = GEU;
    2468            0 :       iter_limit = const0_rtx;
    2469            0 :       iter_incr = GEN_INT (incr);
    2470              :     }
    2471              :   else
    2472              :     {
    2473           48 :       iter_init = const0_rtx;
    2474           48 :       iter_cond = LTU;
    2475           48 :       iter_limit = size;
    2476           48 :       iter_incr = GEN_INT (incr);
    2477              :     }
    2478           48 :   emit_move_insn (iter, iter_init);
    2479              : 
    2480           48 :   opt_scalar_int_mode int_move_mode
    2481           48 :     = int_mode_for_size (incr * BITS_PER_UNIT, 1);
    2482           48 :   if (!int_move_mode.exists (&move_mode)
    2483           96 :       || GET_MODE_BITSIZE (int_move_mode.require ()) != incr * BITS_PER_UNIT)
    2484              :     {
    2485            0 :       move_mode = BLKmode;
    2486            0 :       gcc_checking_assert (can_move_by_pieces (incr, align));
    2487              :     }
    2488              : 
    2489           48 :   x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2490           48 :   y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2491           48 :   do_pending_stack_adjust ();
    2492              : 
    2493           48 :   emit_jump (cmp_label);
    2494           48 :   emit_label (top_label);
    2495              : 
    2496           48 :   tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
    2497           48 :   x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
    2498              : 
    2499           48 :   if (x_addr_mode != y_addr_mode)
    2500            0 :     tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
    2501           48 :   y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
    2502              : 
    2503           48 :   x = change_address (x, move_mode, x_addr);
    2504           48 :   y = change_address (y, move_mode, y_addr);
    2505              : 
    2506           48 :   if (move_mode == BLKmode)
    2507              :     {
    2508            0 :       bool done;
    2509            0 :       emit_block_move_hints (x, y, iter_incr, BLOCK_OP_NO_LIBCALL,
    2510              :                              align, incr, incr, incr, incr,
    2511              :                              false, &done, false);
    2512            0 :       gcc_checking_assert (done);
    2513              :     }
    2514              :   else
    2515           48 :     emit_move_insn (x, y);
    2516              : 
    2517           48 :   if (downwards)
    2518            0 :     emit_label (cmp_label);
    2519              : 
    2520           48 :   tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
    2521              :                              true, OPTAB_LIB_WIDEN);
    2522           48 :   if (tmp != iter)
    2523            0 :     emit_move_insn (iter, tmp);
    2524              : 
    2525           48 :   if (!downwards)
    2526           48 :     emit_label (cmp_label);
    2527              : 
    2528           48 :   emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
    2529              :                            true, top_label,
    2530           48 :                            profile_probability::guessed_always ()
    2531              :                                 .apply_scale (9, 10));
    2532           48 : }
    2533              : 
    2534              : /* Expand a call to memcpy or memmove or memcmp, and return the result.
    2535              :    TAILCALL is true if this is a tail call.  */
    2536              : 
    2537              : rtx
    2538        63935 : emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
    2539              :                            rtx size, bool tailcall)
    2540              : {
    2541        63935 :   rtx dst_addr, src_addr;
    2542        63935 :   tree call_expr, dst_tree, src_tree, size_tree;
    2543        63935 :   machine_mode size_mode;
    2544              : 
    2545              :   /* Since dst and src are passed to a libcall, mark the corresponding
    2546              :      tree EXPR as addressable.  */
    2547        63935 :   tree dst_expr = MEM_EXPR (dst);
    2548        63935 :   tree src_expr = MEM_EXPR (src);
    2549        63935 :   if (dst_expr)
    2550        57220 :     mark_addressable (dst_expr);
    2551        63935 :   if (src_expr)
    2552        62532 :     mark_addressable (src_expr);
    2553              : 
    2554        63935 :   dst_addr = copy_addr_to_reg (XEXP (dst, 0));
    2555        63935 :   dst_addr = convert_memory_address (ptr_mode, dst_addr);
    2556        63935 :   dst_tree = make_tree (ptr_type_node, dst_addr);
    2557              : 
    2558        63935 :   src_addr = copy_addr_to_reg (XEXP (src, 0));
    2559        63935 :   src_addr = convert_memory_address (ptr_mode, src_addr);
    2560        63935 :   src_tree = make_tree (ptr_type_node, src_addr);
    2561              : 
    2562        63935 :   size_mode = TYPE_MODE (sizetype);
    2563        63935 :   size = convert_to_mode (size_mode, size, 1);
    2564        63935 :   size = copy_to_mode_reg (size_mode, size);
    2565        63935 :   size_tree = make_tree (sizetype, size);
    2566              : 
    2567              :   /* It is incorrect to use the libcall calling conventions for calls to
    2568              :      memcpy/memmove/memcmp because they can be provided by the user.  */
    2569        63935 :   tree fn = builtin_decl_implicit (fncode);
    2570        63935 :   call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
    2571        63935 :   CALL_EXPR_TAILCALL (call_expr) = tailcall;
    2572              : 
    2573        63935 :   return expand_call (call_expr, NULL_RTX, false);
    2574              : }
    2575              : 
    2576              : /* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
    2577              :    ARG3_TYPE is the type of ARG3_RTX.  Return the result rtx on success,
    2578              :    otherwise return null.  */
    2579              : 
    2580              : rtx
    2581       170432 : expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
    2582              :                           rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
    2583              :                           HOST_WIDE_INT align)
    2584              : {
    2585       170432 :   machine_mode insn_mode = insn_data[icode].operand[0].mode;
    2586              : 
    2587       170432 :   if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
    2588              :     target = NULL_RTX;
    2589              : 
    2590       170432 :   class expand_operand ops[5];
    2591       170432 :   create_output_operand (&ops[0], target, insn_mode);
    2592       170432 :   create_fixed_operand (&ops[1], arg1_rtx);
    2593       170432 :   create_fixed_operand (&ops[2], arg2_rtx);
    2594       170432 :   create_convert_operand_from (&ops[3], arg3_rtx, TYPE_MODE (arg3_type),
    2595       170432 :                                TYPE_UNSIGNED (arg3_type));
    2596       170432 :   create_integer_operand (&ops[4], align);
    2597       170432 :   if (maybe_expand_insn (icode, 5, ops))
    2598         5780 :     return ops[0].value;
    2599              :   return NULL_RTX;
    2600              : }
    2601              : 
    2602              : /* Expand a block compare between X and Y with length LEN using the
    2603              :    cmpmem optab, placing the result in TARGET.  LEN_TYPE is the type
    2604              :    of the expression that was used to calculate the length.  ALIGN
    2605              :    gives the known minimum common alignment.  */
    2606              : 
    2607              : static rtx
    2608        42501 : emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2609              :                            unsigned align)
    2610              : {
    2611              :   /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
    2612              :      implementing memcmp because it will stop if it encounters two
    2613              :      zero bytes.  */
    2614        42501 :   insn_code icode = direct_optab_handler (cmpmem_optab, SImode);
    2615              : 
    2616        42501 :   if (icode == CODE_FOR_nothing)
    2617              :     return NULL_RTX;
    2618              : 
    2619        42501 :   return expand_cmpstrn_or_cmpmem (icode, target, x, y, len_type, len, align);
    2620              : }
    2621              : 
    2622              : /* Emit code to compare a block Y to a block X.  This may be done with
    2623              :    string-compare instructions, with multiple scalar instructions,
    2624              :    or with a library call.
    2625              : 
    2626              :    Both X and Y must be MEM rtx's.  LEN is an rtx that says how long
    2627              :    they are.  LEN_TYPE is the type of the expression that was used to
    2628              :    calculate it, and CTZ_LEN is the known trailing-zeros count of LEN,
    2629              :    so LEN must be a multiple of 1<<CTZ_LEN even if it's not constant.
    2630              : 
    2631              :    If EQUALITY_ONLY is true, it means we don't have to return the tri-state
    2632              :    value of a normal memcmp call, instead we can just compare for equality.
    2633              :    If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
    2634              :    returning NULL_RTX.
    2635              : 
    2636              :    Optionally, the caller can pass a constfn and associated data in Y_CFN
    2637              :    and Y_CFN_DATA. describing that the second operand being compared is a
    2638              :    known constant and how to obtain its data.
    2639              :    Return the result of the comparison, or NULL_RTX if we failed to
    2640              :    perform the operation.  */
    2641              : 
    2642              : rtx
    2643       104232 : emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2644              :                       bool equality_only, by_pieces_constfn y_cfn,
    2645              :                       void *y_cfndata, unsigned ctz_len)
    2646              : {
    2647       104232 :   rtx result = 0;
    2648              : 
    2649       104232 :   if (CONST_INT_P (len) && INTVAL (len) == 0)
    2650            0 :     return const0_rtx;
    2651              : 
    2652       104232 :   gcc_assert (MEM_P (x) && MEM_P (y));
    2653       104232 :   unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
    2654       104232 :   gcc_assert (align >= BITS_PER_UNIT);
    2655              : 
    2656       104232 :   x = adjust_address (x, BLKmode, 0);
    2657       104232 :   y = adjust_address (y, BLKmode, 0);
    2658              : 
    2659       104232 :   if (equality_only
    2660        89721 :       && CONST_INT_P (len)
    2661       172580 :       && can_do_by_pieces (INTVAL (len), align, COMPARE_BY_PIECES))
    2662        61731 :     result = compare_by_pieces (x, y, INTVAL (len), target, align,
    2663              :                                 y_cfn, y_cfndata);
    2664              :   else
    2665        42501 :     result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
    2666              : 
    2667       104232 :   if (!result && (flag_inline_stringops & ILSOP_MEMCMP))
    2668          361 :     result = emit_block_cmp_via_loop (x, y, len, len_type,
    2669              :                                       target, equality_only,
    2670              :                                       align, ctz_len);
    2671              : 
    2672              :   return result;
    2673              : }
    2674              : 
    2675              : /* Like emit_block_cmp_hints, but with known alignment and no support
    2676              :    for constats.  Always expand to a loop with iterations that compare
    2677              :    blocks of the largest compare-by-pieces size that divides both len
    2678              :    and align, and then, if !EQUALITY_ONLY, identify the word and then
    2679              :    the unit that first differs to return the result.  */
    2680              : 
    2681              : rtx
    2682          403 : emit_block_cmp_via_loop (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2683              :                          bool equality_only, unsigned align, unsigned ctz_len)
    2684              : {
    2685          403 :   unsigned incr = align / BITS_PER_UNIT;
    2686              : 
    2687          403 :   if (CONST_INT_P (len))
    2688          319 :     ctz_len = MAX (ctz_len, (unsigned) wi::ctz (UINTVAL (len)));
    2689              : 
    2690          403 :   if (HOST_WIDE_INT_1U << ctz_len < (unsigned HOST_WIDE_INT) incr)
    2691          148 :     incr = HOST_WIDE_INT_1U << ctz_len;
    2692              : 
    2693              :   while (incr > 1
    2694          407 :          && !can_do_by_pieces (incr, align, COMPARE_BY_PIECES))
    2695            4 :     incr >>= 1;
    2696              : 
    2697          403 :   rtx_code_label *cmp_label, *top_label, *ne_label, *res_label;
    2698          403 :   rtx iter, x_addr, y_addr, tmp;
    2699          403 :   machine_mode x_addr_mode = get_address_mode (x);
    2700          403 :   machine_mode y_addr_mode = get_address_mode (y);
    2701          403 :   machine_mode iter_mode;
    2702              : 
    2703          403 :   iter_mode = GET_MODE (len);
    2704          403 :   if (iter_mode == VOIDmode)
    2705          319 :     iter_mode = word_mode;
    2706              : 
    2707          403 :   rtx iter_init = const0_rtx;
    2708          403 :   rtx_code iter_cond = LTU;
    2709          403 :   rtx_code entry_cond = GEU;
    2710          403 :   rtx iter_limit = len;
    2711          403 :   rtx iter_incr = GEN_INT (incr);
    2712          403 :   machine_mode cmp_mode;
    2713              : 
    2714              :   /* We can drop the loop back edge if we know there's exactly one
    2715              :      iteration.  */
    2716          403 :   top_label = (!rtx_equal_p (len, iter_incr)
    2717          403 :                ? gen_label_rtx ()
    2718              :                : NULL);
    2719              :   /* We need not test before entering the loop if len is known
    2720              :      nonzero.  ??? This could be even stricter, testing whether a
    2721              :      nonconstant LEN could possibly be zero.  */
    2722          403 :   cmp_label = (!CONSTANT_P (len) || rtx_equal_p (len, iter_init)
    2723          403 :                ? gen_label_rtx ()
    2724              :                : NULL);
    2725          403 :   ne_label = gen_label_rtx ();
    2726          403 :   res_label = gen_label_rtx ();
    2727              : 
    2728          403 :   iter = gen_reg_rtx (iter_mode);
    2729          403 :   emit_move_insn (iter, iter_init);
    2730              : 
    2731          403 :   opt_scalar_int_mode int_cmp_mode
    2732          403 :     = int_mode_for_size (incr * BITS_PER_UNIT, 1);
    2733          403 :   if (!int_cmp_mode.exists (&cmp_mode)
    2734         1206 :       || GET_MODE_BITSIZE (int_cmp_mode.require ()) != incr * BITS_PER_UNIT
    2735          402 :       || !can_compare_p (NE, cmp_mode, ccp_jump))
    2736              :     {
    2737            1 :       cmp_mode = BLKmode;
    2738            1 :       gcc_checking_assert (incr != 1);
    2739              :     }
    2740              : 
    2741              :   /* Save the base addresses.  */
    2742          403 :   x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2743          403 :   y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2744          403 :   do_pending_stack_adjust ();
    2745              : 
    2746          403 :   if (cmp_label)
    2747              :     {
    2748           84 :       if (top_label)
    2749           84 :         emit_jump (cmp_label);
    2750              :       else
    2751            0 :         emit_cmp_and_jump_insns (iter, iter_limit, entry_cond,
    2752              :                                  NULL_RTX, iter_mode,
    2753              :                                  true, cmp_label,
    2754            0 :                                  profile_probability::guessed_always ()
    2755              :                                  .apply_scale (1, 10));
    2756              :     }
    2757          403 :   if (top_label)
    2758          386 :     emit_label (top_label);
    2759              : 
    2760              :   /* Offset the base addresses by ITER.  */
    2761          403 :   tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
    2762          403 :   x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
    2763              : 
    2764          403 :   if (x_addr_mode != y_addr_mode)
    2765            0 :     tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
    2766          403 :   y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
    2767              : 
    2768          403 :   x = change_address (x, cmp_mode, x_addr);
    2769          403 :   y = change_address (y, cmp_mode, y_addr);
    2770              : 
    2771              :   /* Compare one block.  */
    2772          403 :   rtx part_res;
    2773          403 :   if (cmp_mode == BLKmode)
    2774            1 :     part_res = compare_by_pieces (x, y, incr, target, align, 0, 0);
    2775              :   else
    2776          402 :     part_res = expand_binop (cmp_mode, sub_optab, x, y, NULL_RTX,
    2777              :                              true, OPTAB_LIB_WIDEN);
    2778              : 
    2779              :   /* Stop if we found a difference.  */
    2780          806 :   emit_cmp_and_jump_insns (part_res, GEN_INT (0), NE, NULL_RTX,
    2781          403 :                            GET_MODE (part_res), true, ne_label,
    2782          403 :                            profile_probability::guessed_always ()
    2783              :                                 .apply_scale (1, 10));
    2784              : 
    2785              :   /* Increment ITER.  */
    2786          403 :   tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
    2787              :                              true, OPTAB_LIB_WIDEN);
    2788          403 :   if (tmp != iter)
    2789            0 :     emit_move_insn (iter, tmp);
    2790              : 
    2791          403 :   if (cmp_label)
    2792           84 :     emit_label (cmp_label);
    2793              :   /* Loop until we reach the limit.  */
    2794              : 
    2795          403 :   if (top_label)
    2796          386 :     emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
    2797              :                              true, top_label,
    2798          772 :                              profile_probability::guessed_always ()
    2799              :                              .apply_scale (9, 10));
    2800              : 
    2801              :   /* We got to the end without differences, so the result is zero.  */
    2802          403 :   if (target == NULL_RTX
    2803          403 :       || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
    2804           49 :     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
    2805              : 
    2806          403 :   emit_move_insn (target, const0_rtx);
    2807          403 :   emit_jump (res_label);
    2808              : 
    2809          403 :   emit_label (ne_label);
    2810              : 
    2811              :   /* Return nonzero, or pinpoint the difference to return the expected
    2812              :      result for non-equality tests.  */
    2813          403 :   if (equality_only)
    2814            0 :     emit_move_insn (target, const1_rtx);
    2815              :   else
    2816              :     {
    2817          403 :       if (incr > UNITS_PER_WORD)
    2818              :         /* ??? Re-compare the block found to be different one word at a
    2819              :            time.  */
    2820            5 :         part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
    2821              :                                             target, equality_only,
    2822              :                                             BITS_PER_WORD, 0);
    2823          398 :       else if (incr > 1)
    2824              :         /* ??? Re-compare the block found to be different one byte at a
    2825              :            time.  We could do better using part_res, and being careful
    2826              :            about endianness.  */
    2827           37 :         part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
    2828              :                                             target, equality_only,
    2829              :                                             BITS_PER_UNIT, 0);
    2830         1083 :       else if (known_gt (GET_MODE_BITSIZE (GET_MODE (target)),
    2831              :                          GET_MODE_BITSIZE (cmp_mode)))
    2832          361 :         part_res = expand_binop (GET_MODE (target), sub_optab, x, y, target,
    2833              :                                  true, OPTAB_LIB_WIDEN);
    2834              :       else
    2835              :         {
    2836              :           /* In the odd chance target is QImode, we can't count on
    2837              :              widening subtract to capture the result of the unsigned
    2838              :              compares.  */
    2839            0 :           rtx_code_label *ltu_label;
    2840            0 :           ltu_label = gen_label_rtx ();
    2841            0 :           emit_cmp_and_jump_insns (x, y, LTU, NULL_RTX,
    2842              :                                    cmp_mode, true, ltu_label,
    2843            0 :                                    profile_probability::guessed_always ()
    2844              :                                    .apply_scale (5, 10));
    2845              : 
    2846            0 :           emit_move_insn (target, const1_rtx);
    2847            0 :           emit_jump (res_label);
    2848              : 
    2849            0 :           emit_label (ltu_label);
    2850            0 :           emit_move_insn (target, constm1_rtx);
    2851            0 :           part_res = target;
    2852              :         }
    2853              : 
    2854          403 :       if (target != part_res)
    2855            0 :         convert_move (target, part_res, false);
    2856              :     }
    2857              : 
    2858          403 :   emit_label (res_label);
    2859              : 
    2860          403 :   return target;
    2861              : }
    2862              : 
    2863              : 
    2864              : /* Copy all or part of a value X into registers starting at REGNO.
    2865              :    The number of registers to be filled is NREGS.  */
    2866              : 
    2867              : void
    2868          434 : move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
    2869              : {
    2870          434 :   if (nregs == 0)
    2871              :     return;
    2872              : 
    2873          420 :   if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
    2874            0 :     x = validize_mem (force_const_mem (mode, x));
    2875              : 
    2876              :   /* See if the machine can do this with a load multiple insn.  */
    2877          420 :   if (targetm.have_load_multiple ())
    2878              :     {
    2879            0 :       rtx_insn *last = get_last_insn ();
    2880            0 :       rtx first = gen_rtx_REG (word_mode, regno);
    2881            0 :       if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
    2882              :                                                      GEN_INT (nregs)))
    2883              :         {
    2884            0 :           emit_insn (pat);
    2885            0 :           return;
    2886              :         }
    2887              :       else
    2888            0 :         delete_insns_since (last);
    2889              :     }
    2890              : 
    2891          848 :   for (int i = 0; i < nregs; i++)
    2892          428 :     emit_move_insn (gen_rtx_REG (word_mode, regno + i),
    2893          428 :                     operand_subword_force (x, i, mode));
    2894              : }
    2895              : 
    2896              : /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
    2897              :    The number of registers to be filled is NREGS.  */
    2898              : 
    2899              : void
    2900         1216 : move_block_from_reg (int regno, rtx x, int nregs)
    2901              : {
    2902         1216 :   if (nregs == 0)
    2903              :     return;
    2904              : 
    2905              :   /* See if the machine can do this with a store multiple insn.  */
    2906         1216 :   if (targetm.have_store_multiple ())
    2907              :     {
    2908            0 :       rtx_insn *last = get_last_insn ();
    2909            0 :       rtx first = gen_rtx_REG (word_mode, regno);
    2910            0 :       if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
    2911              :                                                       GEN_INT (nregs)))
    2912              :         {
    2913            0 :           emit_insn (pat);
    2914            0 :           return;
    2915              :         }
    2916              :       else
    2917            0 :         delete_insns_since (last);
    2918              :     }
    2919              : 
    2920         2436 :   for (int i = 0; i < nregs; i++)
    2921              :     {
    2922         1220 :       rtx tem = operand_subword (x, i, 1, BLKmode);
    2923              : 
    2924         1220 :       gcc_assert (tem);
    2925              : 
    2926         1220 :       emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
    2927              :     }
    2928              : }
    2929              : 
    2930              : /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
    2931              :    ORIG, where ORIG is a non-consecutive group of registers represented by
    2932              :    a PARALLEL.  The clone is identical to the original except in that the
    2933              :    original set of registers is replaced by a new set of pseudo registers.
    2934              :    The new set has the same modes as the original set.  */
    2935              : 
    2936              : rtx
    2937         3012 : gen_group_rtx (rtx orig)
    2938              : {
    2939         3012 :   int i, length;
    2940         3012 :   rtx *tmps;
    2941              : 
    2942         3012 :   gcc_assert (GET_CODE (orig) == PARALLEL);
    2943              : 
    2944         3012 :   length = XVECLEN (orig, 0);
    2945         3012 :   tmps = XALLOCAVEC (rtx, length);
    2946              : 
    2947              :   /* Skip a NULL entry in first slot.  */
    2948         3012 :   i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
    2949              : 
    2950         3012 :   if (i)
    2951            0 :     tmps[0] = 0;
    2952              : 
    2953         7325 :   for (; i < length; i++)
    2954              :     {
    2955         4313 :       machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
    2956         4313 :       rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
    2957              : 
    2958         4313 :       tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
    2959              :     }
    2960              : 
    2961         3012 :   return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
    2962              : }
    2963              : 
    2964              : /* A subroutine of emit_group_load.  Arguments as for emit_group_load,
    2965              :    except that values are placed in TMPS[i], and must later be moved
    2966              :    into corresponding XEXP (XVECEXP (DST, 0, i), 0) element.  */
    2967              : 
    2968              : static void
    2969       294621 : emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
    2970              :                    poly_int64 ssize)
    2971              : {
    2972       294624 :   rtx src;
    2973       294624 :   int start, i;
    2974       294624 :   machine_mode m = GET_MODE (orig_src);
    2975              : 
    2976       294624 :   gcc_assert (GET_CODE (dst) == PARALLEL);
    2977              : 
    2978       294624 :   if (m != VOIDmode
    2979       275847 :       && !SCALAR_INT_MODE_P (m)
    2980        18899 :       && !MEM_P (orig_src)
    2981         5534 :       && GET_CODE (orig_src) != CONCAT)
    2982              :     {
    2983            3 :       scalar_int_mode imode;
    2984            3 :       if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode))
    2985              :         {
    2986            3 :           src = gen_reg_rtx (imode);
    2987            3 :           emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
    2988              :         }
    2989              :       else
    2990              :         {
    2991            0 :           src = assign_stack_temp (GET_MODE (orig_src), ssize);
    2992            0 :           emit_move_insn (src, orig_src);
    2993              :         }
    2994            3 :       emit_group_load_1 (tmps, dst, src, type, ssize);
    2995              :       return;
    2996              :     }
    2997              : 
    2998              :   /* Check for a NULL entry, used to indicate that the parameter goes
    2999              :      both on the stack and in registers.  */
    3000       294621 :   if (XEXP (XVECEXP (dst, 0, 0), 0))
    3001              :     start = 0;
    3002              :   else
    3003            0 :     start = 1;
    3004              : 
    3005              :   /* Process the pieces.  */
    3006       872507 :   for (i = start; i < XVECLEN (dst, 0); i++)
    3007              :     {
    3008       577886 :       machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
    3009       577886 :       poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
    3010      1155772 :       poly_int64 bytelen = GET_MODE_SIZE (mode);
    3011       577886 :       poly_int64 shift = 0;
    3012              : 
    3013              :       /* Handle trailing fragments that run over the size of the struct.
    3014              :          It's the target's responsibility to make sure that the fragment
    3015              :          cannot be strictly smaller in some cases and strictly larger
    3016              :          in others.  */
    3017       577886 :       gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
    3018       577886 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3019              :         {
    3020              :           /* Arrange to shift the fragment to where it belongs.
    3021              :              extract_bit_field loads to the lsb of the reg.  */
    3022              :           if (
    3023              : #ifdef BLOCK_REG_PADDING
    3024              :               BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
    3025              :               == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
    3026              : #else
    3027              :               BYTES_BIG_ENDIAN
    3028              : #endif
    3029              :               )
    3030              :             shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
    3031         1794 :           bytelen = ssize - bytepos;
    3032         1794 :           gcc_assert (maybe_gt (bytelen, 0));
    3033              :         }
    3034              : 
    3035              :       /* If we won't be loading directly from memory, protect the real source
    3036              :          from strange tricks we might play; but make sure that the source can
    3037              :          be loaded directly into the destination.  */
    3038       577886 :       src = orig_src;
    3039       577886 :       if (!MEM_P (orig_src)
    3040       476848 :           && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
    3041        45952 :           && GET_CODE (orig_src) != CONCAT
    3042       615440 :           && !CONSTANT_P (orig_src))
    3043              :         {
    3044            0 :           gcc_assert (GET_MODE (orig_src) != VOIDmode);
    3045            0 :           src = force_reg (GET_MODE (orig_src), orig_src);
    3046              :         }
    3047              : 
    3048              :       /* Optimize the access just a bit.  */
    3049       577886 :       if (MEM_P (src)
    3050       101038 :           && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
    3051            0 :               || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
    3052       202076 :           && multiple_p (bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
    3053       678924 :           && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3054              :         {
    3055        99263 :           tmps[i] = gen_reg_rtx (mode);
    3056        99263 :           emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
    3057              :         }
    3058       478623 :       else if (COMPLEX_MODE_P (mode)
    3059            0 :                && GET_MODE (src) == mode
    3060       478623 :                && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3061              :         /* Let emit_move_complex do the bulk of the work.  */
    3062            0 :         tmps[i] = src;
    3063       478623 :       else if (GET_CODE (src) == CONCAT)
    3064              :         {
    3065        16796 :           poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
    3066        16796 :           poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
    3067         8398 :           unsigned int elt;
    3068         8398 :           poly_int64 subpos;
    3069              : 
    3070         8398 :           if (can_div_trunc_p (bytepos, slen0, &elt, &subpos)
    3071         8398 :               && known_le (subpos + bytelen, slen0))
    3072              :             {
    3073              :               /* The following assumes that the concatenated objects all
    3074              :                  have the same size.  In this case, a simple calculation
    3075              :                  can be used to determine the object and the bit field
    3076              :                  to be extracted.  */
    3077         5734 :               tmps[i] = XEXP (src, elt);
    3078         5734 :               if (maybe_ne (subpos, 0)
    3079         5734 :                   || maybe_ne (subpos + bytelen, slen0)
    3080        11468 :                   || (!CONSTANT_P (tmps[i])
    3081         5734 :                       && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
    3082            0 :                 tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
    3083            0 :                                              subpos * BITS_PER_UNIT,
    3084              :                                              1, NULL_RTX, mode, mode, false,
    3085              :                                              NULL);
    3086              :             }
    3087              :           else
    3088              :             {
    3089         2664 :               rtx mem;
    3090              : 
    3091         2664 :               gcc_assert (known_eq (bytepos, 0));
    3092         2664 :               mem = assign_stack_temp (GET_MODE (src), slen);
    3093         2664 :               emit_move_insn (mem, src);
    3094         2664 :               tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
    3095              :                                            0, 1, NULL_RTX, mode, mode, false,
    3096              :                                            NULL);
    3097              :             }
    3098              :         }
    3099       470225 :       else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
    3100        37554 :                && XVECLEN (dst, 0) > 1)
    3101        37554 :         tmps[i] = force_subreg (mode, src, GET_MODE (dst), bytepos);
    3102       432671 :       else if (CONSTANT_P (src))
    3103              :         {
    3104            0 :           if (known_eq (bytelen, ssize))
    3105            0 :             tmps[i] = src;
    3106              :           else
    3107              :             {
    3108              :               rtx first, second;
    3109              : 
    3110              :               /* TODO: const_wide_int can have sizes other than this...  */
    3111            0 :               gcc_assert (known_eq (2 * bytelen, ssize));
    3112            0 :               split_double (src, &first, &second);
    3113            0 :               if (i)
    3114            0 :                 tmps[i] = second;
    3115              :               else
    3116            0 :                 tmps[i] = first;
    3117              :             }
    3118              :         }
    3119       432671 :       else if (REG_P (src) && GET_MODE (src) == mode)
    3120            0 :         tmps[i] = src;
    3121              :       else
    3122       432671 :         tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
    3123       865342 :                                      bytepos * BITS_PER_UNIT, 1, NULL_RTX,
    3124              :                                      mode, mode, false, NULL);
    3125              : 
    3126       577886 :       if (maybe_ne (shift, 0))
    3127              :         tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
    3128              :                                 shift, tmps[i], 0);
    3129              :     }
    3130              : }
    3131              : 
    3132              : /* Emit code to move a block SRC of type TYPE to a block DST,
    3133              :    where DST is non-consecutive registers represented by a PARALLEL.
    3134              :    SSIZE represents the total size of block ORIG_SRC in bytes, or -1
    3135              :    if not known.  */
    3136              : 
    3137              : void
    3138        11045 : emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
    3139              : {
    3140        11045 :   rtx *tmps;
    3141        11045 :   int i;
    3142              : 
    3143        11045 :   tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
    3144        11045 :   emit_group_load_1 (tmps, dst, src, type, ssize);
    3145              : 
    3146              :   /* Copy the extracted pieces into the proper (probable) hard regs.  */
    3147        30888 :   for (i = 0; i < XVECLEN (dst, 0); i++)
    3148              :     {
    3149        19843 :       rtx d = XEXP (XVECEXP (dst, 0, i), 0);
    3150        19843 :       if (d == NULL)
    3151            0 :         continue;
    3152        19843 :       emit_move_insn (d, tmps[i]);
    3153              :     }
    3154        11045 : }
    3155              : 
    3156              : /* Similar, but load SRC into new pseudos in a format that looks like
    3157              :    PARALLEL.  This can later be fed to emit_group_move to get things
    3158              :    in the right place.  */
    3159              : 
    3160              : rtx
    3161       283576 : emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
    3162              : {
    3163       283576 :   rtvec vec;
    3164       283576 :   int i;
    3165              : 
    3166       283576 :   vec = rtvec_alloc (XVECLEN (parallel, 0));
    3167       283576 :   emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
    3168              : 
    3169              :   /* Convert the vector to look just like the original PARALLEL, except
    3170              :      with the computed values.  */
    3171       841619 :   for (i = 0; i < XVECLEN (parallel, 0); i++)
    3172              :     {
    3173       558043 :       rtx e = XVECEXP (parallel, 0, i);
    3174       558043 :       rtx d = XEXP (e, 0);
    3175              : 
    3176       558043 :       if (d)
    3177              :         {
    3178       558043 :           d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
    3179       558043 :           e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
    3180              :         }
    3181       558043 :       RTVEC_ELT (vec, i) = e;
    3182              :     }
    3183              : 
    3184       283576 :   return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
    3185              : }
    3186              : 
    3187              : /* Emit code to move a block SRC to block DST, where SRC and DST are
    3188              :    non-consecutive groups of registers, each represented by a PARALLEL.  */
    3189              : 
    3190              : void
    3191       286588 : emit_group_move (rtx dst, rtx src)
    3192              : {
    3193       286588 :   int i;
    3194              : 
    3195       286588 :   gcc_assert (GET_CODE (src) == PARALLEL
    3196              :               && GET_CODE (dst) == PARALLEL
    3197              :               && XVECLEN (src, 0) == XVECLEN (dst, 0));
    3198              : 
    3199              :   /* Skip first entry if NULL.  */
    3200       848944 :   for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
    3201       562356 :     emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
    3202       562356 :                     XEXP (XVECEXP (src, 0, i), 0));
    3203       286588 : }
    3204              : 
    3205              : /* Move a group of registers represented by a PARALLEL into pseudos.  */
    3206              : 
    3207              : rtx
    3208         5646 : emit_group_move_into_temps (rtx src)
    3209              : {
    3210         5646 :   rtvec vec = rtvec_alloc (XVECLEN (src, 0));
    3211         5646 :   int i;
    3212              : 
    3213        13296 :   for (i = 0; i < XVECLEN (src, 0); i++)
    3214              :     {
    3215         7650 :       rtx e = XVECEXP (src, 0, i);
    3216         7650 :       rtx d = XEXP (e, 0);
    3217              : 
    3218         7650 :       if (d)
    3219         7650 :         e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
    3220         7650 :       RTVEC_ELT (vec, i) = e;
    3221              :     }
    3222              : 
    3223         5646 :   return gen_rtx_PARALLEL (GET_MODE (src), vec);
    3224              : }
    3225              : 
    3226              : /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
    3227              :    where SRC is non-consecutive registers represented by a PARALLEL.
    3228              :    SSIZE represents the total size of block ORIG_DST, or -1 if not
    3229              :    known.  */
    3230              : 
    3231              : void
    3232        64650 : emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
    3233              :                   poly_int64 ssize)
    3234              : {
    3235        64650 :   rtx *tmps, dst;
    3236        64650 :   int start, finish, i;
    3237        64650 :   machine_mode m = GET_MODE (orig_dst);
    3238              : 
    3239        64650 :   gcc_assert (GET_CODE (src) == PARALLEL);
    3240              : 
    3241        64650 :   if (!SCALAR_INT_MODE_P (m)
    3242        14067 :       && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
    3243              :     {
    3244            0 :       scalar_int_mode imode;
    3245            0 :       if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode))
    3246              :         {
    3247            0 :           dst = gen_reg_rtx (imode);
    3248            0 :           emit_group_store (dst, src, type, ssize);
    3249            0 :           dst = gen_lowpart (GET_MODE (orig_dst), dst);
    3250              :         }
    3251              :       else
    3252              :         {
    3253            0 :           dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
    3254            0 :           emit_group_store (dst, src, type, ssize);
    3255              :         }
    3256            0 :       emit_move_insn (orig_dst, dst);
    3257            0 :       return;
    3258              :     }
    3259              : 
    3260              :   /* Check for a NULL entry, used to indicate that the parameter goes
    3261              :      both on the stack and in registers.  */
    3262        64650 :   if (XEXP (XVECEXP (src, 0, 0), 0))
    3263              :     start = 0;
    3264              :   else
    3265            0 :     start = 1;
    3266        64650 :   finish = XVECLEN (src, 0);
    3267              : 
    3268        64650 :   tmps = XALLOCAVEC (rtx, finish);
    3269              : 
    3270              :   /* Copy the (probable) hard regs into pseudos.  */
    3271       185918 :   for (i = start; i < finish; i++)
    3272              :     {
    3273       121268 :       rtx reg = XEXP (XVECEXP (src, 0, i), 0);
    3274       121268 :       if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
    3275              :         {
    3276       113618 :           tmps[i] = gen_reg_rtx (GET_MODE (reg));
    3277       113618 :           emit_move_insn (tmps[i], reg);
    3278              :         }
    3279              :       else
    3280         7650 :         tmps[i] = reg;
    3281              :     }
    3282              : 
    3283              :   /* If we won't be storing directly into memory, protect the real destination
    3284              :      from strange tricks we might play.  */
    3285        64650 :   dst = orig_dst;
    3286        64650 :   if (GET_CODE (dst) == PARALLEL)
    3287              :     {
    3288            0 :       rtx temp;
    3289              : 
    3290              :       /* We can get a PARALLEL dst if there is a conditional expression in
    3291              :          a return statement.  In that case, the dst and src are the same,
    3292              :          so no action is necessary.  */
    3293            0 :       if (rtx_equal_p (dst, src))
    3294              :         return;
    3295              : 
    3296              :       /* It is unclear if we can ever reach here, but we may as well handle
    3297              :          it.  Allocate a temporary, and split this into a store/load to/from
    3298              :          the temporary.  */
    3299            0 :       temp = assign_stack_temp (GET_MODE (dst), ssize);
    3300            0 :       emit_group_store (temp, src, type, ssize);
    3301            0 :       emit_group_load (dst, temp, type, ssize);
    3302            0 :       return;
    3303              :     }
    3304        64650 :   else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
    3305              :     {
    3306        49961 :       machine_mode outer = GET_MODE (dst);
    3307        49961 :       machine_mode inner;
    3308        49961 :       poly_int64 bytepos;
    3309        49961 :       bool done = false;
    3310        49961 :       rtx temp;
    3311              : 
    3312        49961 :       if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
    3313            0 :         dst = gen_reg_rtx (outer);
    3314              : 
    3315              :       /* Make life a bit easier for combine: if the first element of the
    3316              :          vector is the low part of the destination mode, use a paradoxical
    3317              :          subreg to initialize the destination.  */
    3318        49961 :       if (start < finish)
    3319              :         {
    3320        49961 :           inner = GET_MODE (tmps[start]);
    3321        49961 :           bytepos = subreg_lowpart_offset (inner, outer);
    3322        49961 :           if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
    3323              :                         bytepos))
    3324              :             {
    3325        49937 :               temp = force_subreg (outer, tmps[start], inner, 0);
    3326        49937 :               if (temp)
    3327              :                 {
    3328        49280 :                   emit_move_insn (dst, temp);
    3329        49280 :                   done = true;
    3330        49280 :                   start++;
    3331              :                 }
    3332              :             }
    3333              :         }
    3334              : 
    3335              :       /* If the first element wasn't the low part, try the last.  */
    3336        49280 :       if (!done
    3337          681 :           && start < finish - 1)
    3338              :         {
    3339          614 :           inner = GET_MODE (tmps[finish - 1]);
    3340          614 :           bytepos = subreg_lowpart_offset (inner, outer);
    3341          614 :           if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
    3342              :                                                           finish - 1), 1)),
    3343              :                         bytepos))
    3344              :             {
    3345            0 :               temp = force_subreg (outer, tmps[finish - 1], inner, 0);
    3346            0 :               if (temp)
    3347              :                 {
    3348            0 :                   emit_move_insn (dst, temp);
    3349            0 :                   done = true;
    3350            0 :                   finish--;
    3351              :                 }
    3352              :             }
    3353              :         }
    3354              : 
    3355              :       /* Otherwise, simply initialize the result to zero.  */
    3356        49280 :       if (!done)
    3357          681 :         emit_move_insn (dst, CONST0_RTX (outer));
    3358              :     }
    3359              : 
    3360              :   /* Process the pieces.  */
    3361       133260 :   for (i = start; i < finish; i++)
    3362              :     {
    3363        71988 :       poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
    3364        71988 :       machine_mode mode = GET_MODE (tmps[i]);
    3365       143976 :       poly_int64 bytelen = GET_MODE_SIZE (mode);
    3366        71988 :       poly_uint64 adj_bytelen;
    3367        71988 :       rtx dest = dst;
    3368              : 
    3369              :       /* Handle trailing fragments that run over the size of the struct.
    3370              :          It's the target's responsibility to make sure that the fragment
    3371              :          cannot be strictly smaller in some cases and strictly larger
    3372              :          in others.  */
    3373        71988 :       gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
    3374       143150 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3375          826 :         adj_bytelen = ssize - bytepos;
    3376              :       else
    3377        71988 :         adj_bytelen = bytelen;
    3378              : 
    3379              :       /* Deal with destination CONCATs by either storing into one of the parts
    3380              :          or doing a copy after storing into a register or stack temporary.  */
    3381        71988 :       if (GET_CODE (dst) == CONCAT)
    3382              :         {
    3383        27980 :           if (known_le (bytepos + adj_bytelen,
    3384              :                         GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
    3385              :             dest = XEXP (dst, 0);
    3386              : 
    3387        17368 :           else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
    3388              :             {
    3389        10612 :               bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
    3390         5306 :               dest = XEXP (dst, 1);
    3391              :             }
    3392              : 
    3393              :           else
    3394              :             {
    3395         3378 :               machine_mode dest_mode = GET_MODE (dest);
    3396         3378 :               machine_mode tmp_mode = GET_MODE (tmps[i]);
    3397         3378 :               scalar_int_mode dest_imode;
    3398              : 
    3399         3378 :               gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
    3400              : 
    3401              :               /* If the source is a single scalar integer register, and the
    3402              :                  destination has a complex mode for which a same-sized integer
    3403              :                  mode exists, then we can take the left-justified part of the
    3404              :                  source in the complex mode.  */
    3405         3378 :               if (finish == start + 1
    3406         3378 :                   && REG_P (tmps[i])
    3407         3378 :                   && SCALAR_INT_MODE_P (tmp_mode)
    3408         3378 :                   && COMPLEX_MODE_P (dest_mode)
    3409         6756 :                   && int_mode_for_mode (dest_mode).exists (&dest_imode))
    3410              :                 {
    3411         3378 :                   const scalar_int_mode tmp_imode
    3412         3378 :                     = as_a <scalar_int_mode> (tmp_mode);
    3413              : 
    3414         6756 :                   if (GET_MODE_BITSIZE (dest_imode)
    3415         3378 :                       < GET_MODE_BITSIZE (tmp_imode))
    3416              :                     {
    3417           59 :                       dest = gen_reg_rtx (dest_imode);
    3418           59 :                       if (BYTES_BIG_ENDIAN)
    3419              :                         tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
    3420              :                                                 GET_MODE_BITSIZE (tmp_imode)
    3421              :                                                 - GET_MODE_BITSIZE (dest_imode),
    3422              :                                                 NULL_RTX, 1);
    3423           59 :                       emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
    3424           59 :                       dst = gen_lowpart (dest_mode, dest);
    3425              :                     }
    3426              :                   else
    3427         3319 :                     dst = gen_lowpart (dest_mode, tmps[i]);
    3428              :                 }
    3429              : 
    3430              :               /* Otherwise spill the source onto the stack using the more
    3431              :                  aligned of the two modes.  */
    3432            0 :               else if (GET_MODE_ALIGNMENT (dest_mode)
    3433            0 :                        >= GET_MODE_ALIGNMENT (tmp_mode))
    3434              :                 {
    3435            0 :                   dest = assign_stack_temp (dest_mode,
    3436            0 :                                             GET_MODE_SIZE (dest_mode));
    3437            0 :                   emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
    3438              :                                   tmps[i]);
    3439            0 :                   dst = dest;
    3440              :                 }
    3441              : 
    3442              :               else
    3443              :                 {
    3444            0 :                   dest = assign_stack_temp (tmp_mode,
    3445            0 :                                             GET_MODE_SIZE (tmp_mode));
    3446            0 :                   emit_move_insn (dest, tmps[i]);
    3447            0 :                   dst = adjust_address (dest, dest_mode, bytepos);
    3448              :                 }
    3449              : 
    3450              :               break;
    3451              :             }
    3452              :         }
    3453              : 
    3454              :       /* Handle trailing fragments that run over the size of the struct.  */
    3455        68610 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3456              :         {
    3457              :           /* store_bit_field always takes its value from the lsb.
    3458              :              Move the fragment to the lsb if it's not already there.  */
    3459          767 :           if (
    3460              : #ifdef BLOCK_REG_PADDING
    3461              :               BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
    3462              :               == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
    3463              : #else
    3464              :               BYTES_BIG_ENDIAN
    3465              : #endif
    3466              :               )
    3467              :             {
    3468              :               poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
    3469              :               tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
    3470              :                                       shift, tmps[i], 0);
    3471              :             }
    3472              : 
    3473              :           /* Make sure not to write past the end of the struct.  */
    3474          767 :           store_bit_field (dest,
    3475          767 :                            adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
    3476         2301 :                            bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
    3477              :                            VOIDmode, tmps[i], false, false);
    3478              :         }
    3479              : 
    3480              :       /* Optimize the access just a bit.  */
    3481        67843 :       else if (MEM_P (dest)
    3482         7489 :                && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
    3483            0 :                    || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
    3484        14978 :                && multiple_p (bytepos * BITS_PER_UNIT,
    3485              :                               GET_MODE_ALIGNMENT (mode))
    3486        75332 :                && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3487         7489 :         emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
    3488              : 
    3489              :       else
    3490       120708 :         store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
    3491              :                          0, 0, mode, tmps[i], false, false);
    3492              :     }
    3493              : 
    3494              :   /* Copy from the pseudo into the (probable) hard reg.  */
    3495        64650 :   if (orig_dst != dst)
    3496         3378 :     emit_move_insn (orig_dst, dst);
    3497              : }
    3498              : 
    3499              : /* Return a form of X that does not use a PARALLEL.  TYPE is the type
    3500              :    of the value stored in X.  */
    3501              : 
    3502              : rtx
    3503       329968 : maybe_emit_group_store (rtx x, tree type)
    3504              : {
    3505       329968 :   machine_mode mode = TYPE_MODE (type);
    3506       329968 :   gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
    3507       329968 :   if (GET_CODE (x) == PARALLEL)
    3508              :     {
    3509            0 :       rtx result = gen_reg_rtx (mode);
    3510            0 :       emit_group_store (result, x, type, int_size_in_bytes (type));
    3511            0 :       return result;
    3512              :     }
    3513              :   return x;
    3514              : }
    3515              : 
    3516              : /* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
    3517              : 
    3518              :    This is used on targets that return BLKmode values in registers.  */
    3519              : 
    3520              : static void
    3521          249 : copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
    3522              : {
    3523          249 :   unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
    3524          249 :   rtx src = NULL, dst = NULL;
    3525          249 :   unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
    3526          249 :   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
    3527              :   /* No current ABI uses variable-sized modes to pass a BLKmnode type.  */
    3528          249 :   fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
    3529          249 :   fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
    3530          249 :   fixed_size_mode copy_mode;
    3531              : 
    3532              :   /* BLKmode registers created in the back-end shouldn't have survived.  */
    3533          249 :   gcc_assert (mode != BLKmode);
    3534              : 
    3535              :   /* If the structure doesn't take up a whole number of words, see whether
    3536              :      SRCREG is padded on the left or on the right.  If it's on the left,
    3537              :      set PADDING_CORRECTION to the number of bits to skip.
    3538              : 
    3539              :      In most ABIs, the structure will be returned at the least end of
    3540              :      the register, which translates to right padding on little-endian
    3541              :      targets and left padding on big-endian targets.  The opposite
    3542              :      holds if the structure is returned at the most significant
    3543              :      end of the register.  */
    3544          249 :   if (bytes % UNITS_PER_WORD != 0
    3545          249 :       && (targetm.calls.return_in_msb (type)
    3546          218 :           ? !BYTES_BIG_ENDIAN
    3547              :           : BYTES_BIG_ENDIAN))
    3548            0 :     padding_correction
    3549            0 :       = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
    3550              : 
    3551              :   /* We can use a single move if we have an exact mode for the size.  */
    3552          249 :   else if (MEM_P (target)
    3553          249 :            && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
    3554            0 :                || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
    3555          498 :            && bytes == GET_MODE_SIZE (mode))
    3556              :   {
    3557           38 :     emit_move_insn (adjust_address (target, mode, 0), srcreg);
    3558           38 :     return;
    3559              :   }
    3560              : 
    3561              :   /* And if we additionally have the same mode for a register.  */
    3562          211 :   else if (REG_P (target)
    3563            0 :            && GET_MODE (target) == mode
    3564          211 :            && bytes == GET_MODE_SIZE (mode))
    3565              :   {
    3566            0 :     emit_move_insn (target, srcreg);
    3567            0 :     return;
    3568              :   }
    3569              : 
    3570              :   /* This code assumes srcreg is at least a full word.  If it isn't, copy it
    3571              :      into a new pseudo which is a full word.  */
    3572          422 :   if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
    3573              :     {
    3574           76 :       srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
    3575           76 :       mode = word_mode;
    3576              :     }
    3577              : 
    3578              :   /* Copy the structure BITSIZE bits at a time.  If the target lives in
    3579              :      memory, take care of not reading/writing past its end by selecting
    3580              :      a copy mode suited to BITSIZE.  This should always be possible given
    3581              :      how it is computed.
    3582              : 
    3583              :      If the target lives in register, make sure not to select a copy mode
    3584              :      larger than the mode of the register.
    3585              : 
    3586              :      We could probably emit more efficient code for machines which do not use
    3587              :      strict alignment, but it doesn't seem worth the effort at the current
    3588              :      time.  */
    3589              : 
    3590          211 :   copy_mode = word_mode;
    3591          211 :   if (MEM_P (target))
    3592              :     {
    3593          211 :       opt_scalar_int_mode mem_mode = int_mode_for_size (bitsize, 1);
    3594          211 :       if (mem_mode.exists ())
    3595          211 :         copy_mode = mem_mode.require ();
    3596              :     }
    3597            0 :   else if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    3598              :     copy_mode = tmode;
    3599              : 
    3600          211 :   for (bitpos = 0, xbitpos = padding_correction;
    3601         1035 :        bitpos < bytes * BITS_PER_UNIT;
    3602          824 :        bitpos += bitsize, xbitpos += bitsize)
    3603              :     {
    3604              :       /* We need a new source operand each time xbitpos is on a
    3605              :          word boundary and when xbitpos == padding_correction
    3606              :          (the first time through).  */
    3607          824 :       if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
    3608          211 :         src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
    3609              : 
    3610              :       /* We need a new destination operand each time bitpos is on
    3611              :          a word boundary.  */
    3612          824 :       if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    3613              :         dst = target;
    3614          824 :       else if (bitpos % BITS_PER_WORD == 0)
    3615          211 :         dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
    3616              : 
    3617              :       /* Use xbitpos for the source extraction (right justified) and
    3618              :          bitpos for the destination store (left justified).  */
    3619          824 :       store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
    3620          824 :                        extract_bit_field (src, bitsize,
    3621          824 :                                           xbitpos % BITS_PER_WORD, 1,
    3622              :                                           NULL_RTX, copy_mode, copy_mode,
    3623              :                                           false, NULL),
    3624              :                        false, false);
    3625              :     }
    3626              : }
    3627              : 
    3628              : /* Copy BLKmode value SRC into a register of mode MODE_IN.  Return the
    3629              :    register if it contains any data, otherwise return null.
    3630              : 
    3631              :    This is used on targets that return BLKmode values in registers.  */
    3632              : 
    3633              : rtx
    3634         3455 : copy_blkmode_to_reg (machine_mode mode_in, tree src)
    3635              : {
    3636         3455 :   int i, n_regs;
    3637         3455 :   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
    3638         3455 :   unsigned int bitsize;
    3639         3455 :   rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
    3640              :   /* No current ABI uses variable-sized modes to pass a BLKmnode type.  */
    3641         3455 :   fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
    3642         3455 :   fixed_size_mode dst_mode;
    3643         3455 :   scalar_int_mode min_mode;
    3644              : 
    3645         3455 :   gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
    3646              : 
    3647         3455 :   x = expand_normal (src);
    3648              : 
    3649         3455 :   bytes = arg_int_size_in_bytes (TREE_TYPE (src));
    3650         3455 :   if (bytes == 0)
    3651              :     return NULL_RTX;
    3652              : 
    3653              :   /* If the structure doesn't take up a whole number of words, see
    3654              :      whether the register value should be padded on the left or on
    3655              :      the right.  Set PADDING_CORRECTION to the number of padding
    3656              :      bits needed on the left side.
    3657              : 
    3658              :      In most ABIs, the structure will be returned at the least end of
    3659              :      the register, which translates to right padding on little-endian
    3660              :      targets and left padding on big-endian targets.  The opposite
    3661              :      holds if the structure is returned at the most significant
    3662              :      end of the register.  */
    3663         1224 :   if (bytes % UNITS_PER_WORD != 0
    3664         1224 :       && (targetm.calls.return_in_msb (TREE_TYPE (src))
    3665         1188 :           ? !BYTES_BIG_ENDIAN
    3666              :           : BYTES_BIG_ENDIAN))
    3667            0 :     padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
    3668            0 :                                            * BITS_PER_UNIT));
    3669              : 
    3670         1224 :   n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
    3671         1224 :   dst_words = XALLOCAVEC (rtx, n_regs);
    3672         1224 :   bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
    3673         1224 :   min_mode = smallest_int_mode_for_size (bitsize).require ();
    3674              : 
    3675              :   /* Copy the structure BITSIZE bits at a time.  */
    3676         1224 :   for (bitpos = 0, xbitpos = padding_correction;
    3677         3974 :        bitpos < bytes * BITS_PER_UNIT;
    3678         2750 :        bitpos += bitsize, xbitpos += bitsize)
    3679              :     {
    3680              :       /* We need a new destination pseudo each time xbitpos is
    3681              :          on a word boundary and when xbitpos == padding_correction
    3682              :          (the first time through).  */
    3683         2750 :       if (xbitpos % BITS_PER_WORD == 0
    3684         1523 :           || xbitpos == padding_correction)
    3685              :         {
    3686              :           /* Generate an appropriate register.  */
    3687         1227 :           dst_word = gen_reg_rtx (word_mode);
    3688         1227 :           dst_words[xbitpos / BITS_PER_WORD] = dst_word;
    3689              : 
    3690              :           /* Clear the destination before we move anything into it.  */
    3691         1227 :           emit_move_insn (dst_word, CONST0_RTX (word_mode));
    3692              :         }
    3693              : 
    3694              :       /* Find the largest integer mode that can be used to copy all or as
    3695              :          many bits as possible of the structure if the target supports larger
    3696              :          copies.  There are too many corner cases here w.r.t to alignments on
    3697              :          the read/writes.  So if there is any padding just use single byte
    3698              :          operations.  */
    3699         2750 :       opt_scalar_int_mode mode_iter;
    3700         2750 :       if (padding_correction == 0 && !STRICT_ALIGNMENT)
    3701              :         {
    3702         7488 :           FOR_EACH_MODE_FROM (mode_iter, min_mode)
    3703              :             {
    3704         7488 :               unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
    3705         7488 :               if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
    3706         4741 :                   && msize <= BITS_PER_WORD)
    3707         4738 :                 bitsize = msize;
    3708              :               else
    3709              :                 break;
    3710              :             }
    3711              :         }
    3712              : 
    3713              :       /* We need a new source operand each time bitpos is on a word
    3714              :          boundary.  */
    3715         2750 :       if (bitpos % BITS_PER_WORD == 0)
    3716         1227 :         src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
    3717              : 
    3718              :       /* Use bitpos for the source extraction (left justified) and
    3719              :          xbitpos for the destination store (right justified).  */
    3720         5500 :       store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
    3721              :                        0, 0, word_mode,
    3722         2750 :                        extract_bit_field (src_word, bitsize,
    3723         2750 :                                           bitpos % BITS_PER_WORD, 1,
    3724              :                                           NULL_RTX, word_mode, word_mode,
    3725              :                                           false, NULL),
    3726              :                        false, false);
    3727              :     }
    3728              : 
    3729         1224 :   if (mode == BLKmode)
    3730              :     {
    3731              :       /* Find the smallest integer mode large enough to hold the
    3732              :          entire structure.  */
    3733            0 :       opt_scalar_int_mode mode_iter;
    3734            0 :       FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    3735            0 :         if (GET_MODE_SIZE (mode_iter.require ()) >= bytes)
    3736              :           break;
    3737              : 
    3738              :       /* A suitable mode should have been found.  */
    3739            0 :       mode = mode_iter.require ();
    3740              :     }
    3741              : 
    3742         3672 :   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
    3743              :     dst_mode = word_mode;
    3744              :   else
    3745          498 :     dst_mode = mode;
    3746         1224 :   dst = gen_reg_rtx (dst_mode);
    3747              : 
    3748         3675 :   for (i = 0; i < n_regs; i++)
    3749         1227 :     emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
    3750              : 
    3751         1224 :   if (mode != dst_mode)
    3752          726 :     dst = gen_lowpart (mode, dst);
    3753              : 
    3754              :   return dst;
    3755              : }
    3756              : 
    3757              : /* Add a USE expression for REG to the (possibly empty) list pointed
    3758              :    to by CALL_FUSAGE.  REG must denote a hard register.  */
    3759              : 
    3760              : void
    3761     11205727 : use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
    3762              : {
    3763     11205727 :   gcc_assert (REG_P (reg));
    3764              : 
    3765     11205727 :   if (!HARD_REGISTER_P (reg))
    3766              :     return;
    3767              : 
    3768     11205727 :   *call_fusage
    3769     11205727 :     = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
    3770              : }
    3771              : 
    3772              : /* Add a CLOBBER expression for REG to the (possibly empty) list pointed
    3773              :    to by CALL_FUSAGE.  REG must denote a hard register.  */
    3774              : 
    3775              : void
    3776       797877 : clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
    3777              : {
    3778       797877 :   gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
    3779              : 
    3780       797877 :   *call_fusage
    3781       797877 :     = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
    3782       797877 : }
    3783              : 
    3784              : /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
    3785              :    starting at REGNO.  All of these registers must be hard registers.  */
    3786              : 
    3787              : void
    3788         1594 : use_regs (rtx *call_fusage, int regno, int nregs)
    3789              : {
    3790         1594 :   int i;
    3791              : 
    3792         1594 :   gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
    3793              : 
    3794         3196 :   for (i = 0; i < nregs; i++)
    3795         1602 :     use_reg (call_fusage, regno_reg_rtx[regno + i]);
    3796         1594 : }
    3797              : 
    3798              : /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
    3799              :    PARALLEL REGS.  This is for calls that pass values in multiple
    3800              :    non-contiguous locations.  The Irix 6 ABI has examples of this.  */
    3801              : 
    3802              : void
    3803       290534 : use_group_regs (rtx *call_fusage, rtx regs)
    3804              : {
    3805       290534 :   int i;
    3806              : 
    3807       862493 :   for (i = 0; i < XVECLEN (regs, 0); i++)
    3808              :     {
    3809       571959 :       rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
    3810              : 
    3811              :       /* A NULL entry means the parameter goes both on the stack and in
    3812              :          registers.  This can also be a MEM for targets that pass values
    3813              :          partially on the stack and partially in registers.  */
    3814       571959 :       if (reg != 0 && REG_P (reg))
    3815       571959 :         use_reg (call_fusage, reg);
    3816              :     }
    3817       290534 : }
    3818              : 
    3819              : /* Return the defining gimple statement for SSA_NAME NAME if it is an
    3820              :    assigment and the code of the expresion on the RHS is CODE.  Return
    3821              :    NULL otherwise.  */
    3822              : 
    3823              : static gimple *
    3824     11679181 : get_def_for_expr (tree name, enum tree_code code)
    3825              : {
    3826     11679181 :   gimple *def_stmt;
    3827              : 
    3828     11679181 :   if (TREE_CODE (name) != SSA_NAME)
    3829              :     return NULL;
    3830              : 
    3831      9092846 :   def_stmt = get_gimple_for_ssa_name (name);
    3832      9092846 :   if (!def_stmt
    3833      1963785 :       || !is_gimple_assign (def_stmt)
    3834     11055201 :       || gimple_assign_rhs_code (def_stmt) != code)
    3835              :     return NULL;
    3836              : 
    3837              :   return def_stmt;
    3838              : }
    3839              : 
    3840              : /* Return the defining gimple statement for SSA_NAME NAME if it is an
    3841              :    assigment and the class of the expresion on the RHS is CLASS.  Return
    3842              :    NULL otherwise.  */
    3843              : 
    3844              : static gimple *
    3845        16535 : get_def_for_expr_class (tree name, enum tree_code_class tclass)
    3846              : {
    3847        16535 :   gimple *def_stmt;
    3848              : 
    3849        16535 :   if (TREE_CODE (name) != SSA_NAME)
    3850              :     return NULL;
    3851              : 
    3852        16535 :   def_stmt = get_gimple_for_ssa_name (name);
    3853        16535 :   if (!def_stmt
    3854        14440 :       || !is_gimple_assign (def_stmt)
    3855        30975 :       || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
    3856              :     return NULL;
    3857              : 
    3858              :   return def_stmt;
    3859              : }
    3860              : 
    3861              : /* Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
    3862              :    its length in bytes.  */
    3863              : 
    3864              : rtx
    3865       145544 : clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
    3866              :                      unsigned int expected_align, HOST_WIDE_INT expected_size,
    3867              :                      unsigned HOST_WIDE_INT min_size,
    3868              :                      unsigned HOST_WIDE_INT max_size,
    3869              :                      unsigned HOST_WIDE_INT probable_max_size,
    3870              :                      unsigned ctz_size)
    3871              : {
    3872       145544 :   machine_mode mode = GET_MODE (object);
    3873       145544 :   unsigned int align;
    3874              : 
    3875       145544 :   gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
    3876              : 
    3877              :   /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
    3878              :      just move a zero.  Otherwise, do this a piece at a time.  */
    3879       145544 :   poly_int64 size_val;
    3880       145544 :   if (mode != BLKmode
    3881        54707 :       && poly_int_rtx_p (size, &size_val)
    3882       200251 :       && known_eq (size_val, GET_MODE_SIZE (mode)))
    3883              :     {
    3884        54707 :       rtx zero = CONST0_RTX (mode);
    3885        54707 :       if (zero != NULL)
    3886              :         {
    3887        54707 :           emit_move_insn (object, zero);
    3888        54707 :           return NULL;
    3889              :         }
    3890              : 
    3891            0 :       if (COMPLEX_MODE_P (mode))
    3892              :         {
    3893            0 :           zero = CONST0_RTX (GET_MODE_INNER (mode));
    3894            0 :           if (zero != NULL)
    3895              :             {
    3896            0 :               write_complex_part (object, zero, 0, true);
    3897            0 :               write_complex_part (object, zero, 1, false);
    3898            0 :               return NULL;
    3899              :             }
    3900              :         }
    3901              :     }
    3902              : 
    3903        90837 :   if (size == const0_rtx)
    3904              :     return NULL;
    3905              : 
    3906        90837 :   align = MEM_ALIGN (object);
    3907              : 
    3908        90837 :   if (CONST_INT_P (size)
    3909       174516 :       && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
    3910              :                                                  CLEAR_BY_PIECES,
    3911        83679 :                                                  optimize_insn_for_speed_p ()))
    3912        65722 :     clear_by_pieces (object, INTVAL (size), align);
    3913        25115 :   else if (set_storage_via_setmem (object, size, const0_rtx, align,
    3914              :                                    expected_align, expected_size,
    3915              :                                    min_size, max_size, probable_max_size))
    3916              :     ;
    3917        15505 :   else if (try_store_by_multiple_pieces (object, size, ctz_size,
    3918              :                                          min_size, max_size,
    3919              :                                          NULL_RTX, 0, align))
    3920              :     ;
    3921        15242 :   else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
    3922        15242 :     return set_storage_via_libcall (object, size, const0_rtx,
    3923        15242 :                                     method == BLOCK_OP_TAILCALL);
    3924              :   else
    3925            0 :     gcc_unreachable ();
    3926              : 
    3927              :   return NULL;
    3928              : }
    3929              : 
    3930              : rtx
    3931       107123 : clear_storage (rtx object, rtx size, enum block_op_methods method)
    3932              : {
    3933       107123 :   unsigned HOST_WIDE_INT max, min = 0;
    3934       107123 :   if (GET_CODE (size) == CONST_INT)
    3935       107123 :     min = max = UINTVAL (size);
    3936              :   else
    3937            0 :     max = GET_MODE_MASK (GET_MODE (size));
    3938       107123 :   return clear_storage_hints (object, size, method, 0, -1, min, max, max, 0);
    3939              : }
    3940              : 
    3941              : 
    3942              : /* A subroutine of clear_storage.  Expand a call to memset.
    3943              :    Return the return value of memset, 0 otherwise.  */
    3944              : 
    3945              : rtx
    3946        15246 : set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
    3947              : {
    3948        15246 :   tree call_expr, fn, object_tree, size_tree, val_tree;
    3949        15246 :   machine_mode size_mode;
    3950              : 
    3951        15246 :   object = copy_addr_to_reg (XEXP (object, 0));
    3952        15246 :   object_tree = make_tree (ptr_type_node, object);
    3953              : 
    3954        15246 :   if (!CONST_INT_P (val))
    3955            3 :     val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
    3956        15246 :   val_tree = make_tree (integer_type_node, val);
    3957              : 
    3958        15246 :   size_mode = TYPE_MODE (sizetype);
    3959        15246 :   size = convert_to_mode (size_mode, size, 1);
    3960        15246 :   size = copy_to_mode_reg (size_mode, size);
    3961        15246 :   size_tree = make_tree (sizetype, size);
    3962              : 
    3963              :   /* It is incorrect to use the libcall calling conventions for calls to
    3964              :      memset because it can be provided by the user.  */
    3965        15246 :   fn = builtin_decl_implicit (BUILT_IN_MEMSET);
    3966        15246 :   call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
    3967        15246 :   CALL_EXPR_TAILCALL (call_expr) = tailcall;
    3968              : 
    3969        15246 :   return expand_call (call_expr, NULL_RTX, false);
    3970              : }
    3971              : 
    3972              : /* Expand a setmem pattern; return true if successful.  */
    3973              : 
    3974              : bool
    3975        33656 : set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
    3976              :                         unsigned int expected_align, HOST_WIDE_INT expected_size,
    3977              :                         unsigned HOST_WIDE_INT min_size,
    3978              :                         unsigned HOST_WIDE_INT max_size,
    3979              :                         unsigned HOST_WIDE_INT probable_max_size)
    3980              : {
    3981              :   /* Try the most limited insn first, because there's no point
    3982              :      including more than one in the machine description unless
    3983              :      the more limited one has some advantage.  */
    3984              : 
    3985        33656 :   if (expected_align < align)
    3986              :     expected_align = align;
    3987        33656 :   if (expected_size != -1)
    3988              :     {
    3989            5 :       if ((unsigned HOST_WIDE_INT)expected_size > max_size)
    3990            0 :         expected_size = max_size;
    3991            5 :       if ((unsigned HOST_WIDE_INT)expected_size < min_size)
    3992            0 :         expected_size = min_size;
    3993              :     }
    3994              : 
    3995        33656 :   opt_scalar_int_mode mode_iter;
    3996       211262 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    3997              :     {
    3998       189348 :       scalar_int_mode mode = mode_iter.require ();
    3999       189348 :       enum insn_code code = direct_optab_handler (setmem_optab, mode);
    4000              : 
    4001       189348 :       if (code != CODE_FOR_nothing
    4002              :           /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
    4003              :              here because if SIZE is less than the mode mask, as it is
    4004              :              returned by the macro, it will definitely be less than the
    4005              :              actual mode mask.  Since SIZE is within the Pmode address
    4006              :              space, we limit MODE to Pmode.  */
    4007       189348 :           && ((CONST_INT_P (size)
    4008        28029 :                && ((unsigned HOST_WIDE_INT) INTVAL (size)
    4009        28029 :                    <= (GET_MODE_MASK (mode) >> 1)))
    4010        26681 :               || max_size <= (GET_MODE_MASK (mode) >> 1)
    4011        29114 :               || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
    4012              :         {
    4013        44318 :           class expand_operand ops[9];
    4014        44318 :           unsigned int nops;
    4015              : 
    4016        44318 :           nops = insn_data[(int) code].n_generator_args;
    4017        44318 :           gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
    4018              : 
    4019        44318 :           create_fixed_operand (&ops[0], object);
    4020              :           /* The check above guarantees that this size conversion is valid.  */
    4021        44318 :           create_convert_operand_to (&ops[1], size, mode, true);
    4022        44318 :           create_convert_operand_from (&ops[2], val, byte_mode, true);
    4023        44318 :           create_integer_operand (&ops[3], align / BITS_PER_UNIT);
    4024        44318 :           if (nops >= 6)
    4025              :             {
    4026        44318 :               create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
    4027        44318 :               create_integer_operand (&ops[5], expected_size);
    4028              :             }
    4029        44318 :           if (nops >= 8)
    4030              :             {
    4031        44318 :               create_integer_operand (&ops[6], min_size);
    4032              :               /* If we cannot represent the maximal size,
    4033              :                  make parameter NULL.  */
    4034        44318 :               if ((HOST_WIDE_INT) max_size != -1)
    4035        42301 :                 create_integer_operand (&ops[7], max_size);
    4036              :               else
    4037         2017 :                 create_fixed_operand (&ops[7], NULL);
    4038              :             }
    4039        44318 :           if (nops == 9)
    4040              :             {
    4041              :               /* If we cannot represent the maximal size,
    4042              :                  make parameter NULL.  */
    4043        44318 :               if ((HOST_WIDE_INT) probable_max_size != -1)
    4044        42821 :                 create_integer_operand (&ops[8], probable_max_size);
    4045              :               else
    4046         1497 :                 create_fixed_operand (&ops[8], NULL);
    4047              :             }
    4048        44318 :           if (maybe_expand_insn (code, nops, ops))
    4049        11742 :             return true;
    4050              :         }
    4051              :     }
    4052              : 
    4053              :   return false;
    4054              : }
    4055              : 
    4056              : 
    4057              : /* Write to one of the components of the complex value CPLX.  Write VAL to
    4058              :    the real part if IMAG_P is false, and the imaginary part if its true.
    4059              :    If UNDEFINED_P then the value in CPLX is currently undefined.  */
    4060              : 
    4061              : void
    4062       538666 : write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
    4063              : {
    4064       538666 :   machine_mode cmode;
    4065       538666 :   scalar_mode imode;
    4066       538666 :   unsigned ibitsize;
    4067              : 
    4068       538666 :   if (GET_CODE (cplx) == CONCAT)
    4069              :     {
    4070       475526 :       emit_move_insn (XEXP (cplx, imag_p), val);
    4071       475526 :       return;
    4072              :     }
    4073              : 
    4074        63140 :   cmode = GET_MODE (cplx);
    4075        63140 :   imode = GET_MODE_INNER (cmode);
    4076        63140 :   ibitsize = GET_MODE_BITSIZE (imode);
    4077              : 
    4078              :   /* For MEMs simplify_gen_subreg may generate an invalid new address
    4079              :      because, e.g., the original address is considered mode-dependent
    4080              :      by the target, which restricts simplify_subreg from invoking
    4081              :      adjust_address_nv.  Instead of preparing fallback support for an
    4082              :      invalid address, we call adjust_address_nv directly.  */
    4083        63140 :   if (MEM_P (cplx))
    4084              :     {
    4085        76326 :       emit_move_insn (adjust_address_nv (cplx, imode,
    4086              :                                          imag_p ? GET_MODE_SIZE (imode) : 0),
    4087              :                       val);
    4088        50884 :       return;
    4089              :     }
    4090              : 
    4091              :   /* If the sub-object is at least word sized, then we know that subregging
    4092              :      will work.  This special case is important, since store_bit_field
    4093              :      wants to operate on integer modes, and there's rarely an OImode to
    4094              :      correspond to TCmode.  */
    4095        12256 :   if (ibitsize >= BITS_PER_WORD
    4096              :       /* For hard regs we have exact predicates.  Assume we can split
    4097              :          the original object if it spans an even number of hard regs.
    4098              :          This special case is important for SCmode on 64-bit platforms
    4099              :          where the natural size of floating-point regs is 32-bit.  */
    4100        12256 :       || (REG_P (cplx)
    4101         7308 :           && REGNO (cplx) < FIRST_PSEUDO_REGISTER
    4102         7122 :           && REG_NREGS (cplx) % 2 == 0))
    4103              :     {
    4104         4964 :       rtx part = simplify_gen_subreg (imode, cplx, cmode,
    4105         7446 :                                       imag_p ? GET_MODE_SIZE (imode) : 0);
    4106         4964 :       if (part)
    4107              :         {
    4108         4964 :           emit_move_insn (part, val);
    4109         4964 :           return;
    4110              :         }
    4111              :       else
    4112              :         /* simplify_gen_subreg may fail for sub-word MEMs.  */
    4113            0 :         gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
    4114              :     }
    4115              : 
    4116        10938 :   store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
    4117              :                    false, undefined_p);
    4118              : }
    4119              : 
    4120              : /* Extract one of the components of the complex value CPLX.  Extract the
    4121              :    real part if IMAG_P is false, and the imaginary part if it's true.  */
    4122              : 
    4123              : rtx
    4124       487016 : read_complex_part (rtx cplx, bool imag_p)
    4125              : {
    4126       487016 :   machine_mode cmode;
    4127       487016 :   scalar_mode imode;
    4128       487016 :   unsigned ibitsize;
    4129              : 
    4130       487016 :   if (GET_CODE (cplx) == CONCAT)
    4131       309549 :     return XEXP (cplx, imag_p);
    4132              : 
    4133       177467 :   cmode = GET_MODE (cplx);
    4134       177467 :   imode = GET_MODE_INNER (cmode);
    4135       177467 :   ibitsize = GET_MODE_BITSIZE (imode);
    4136              : 
    4137              :   /* Special case reads from complex constants that got spilled to memory.  */
    4138       177467 :   if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
    4139              :     {
    4140        37961 :       tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
    4141        37961 :       if (decl && TREE_CODE (decl) == COMPLEX_CST)
    4142              :         {
    4143            0 :           tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
    4144            0 :           if (CONSTANT_CLASS_P (part))
    4145            0 :             return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
    4146              :         }
    4147              :     }
    4148              : 
    4149              :   /* For MEMs simplify_gen_subreg may generate an invalid new address
    4150              :      because, e.g., the original address is considered mode-dependent
    4151              :      by the target, which restricts simplify_subreg from invoking
    4152              :      adjust_address_nv.  Instead of preparing fallback support for an
    4153              :      invalid address, we call adjust_address_nv directly.  */
    4154       177467 :   if (MEM_P (cplx))
    4155       234788 :     return adjust_address_nv (cplx, imode,
    4156              :                               imag_p ? GET_MODE_SIZE (imode) : 0);
    4157              : 
    4158              :   /* If the sub-object is at least word sized, then we know that subregging
    4159              :      will work.  This special case is important, since extract_bit_field
    4160              :      wants to operate on integer modes, and there's rarely an OImode to
    4161              :      correspond to TCmode.  */
    4162        20842 :   if (ibitsize >= BITS_PER_WORD
    4163              :       /* For hard regs we have exact predicates.  Assume we can split
    4164              :          the original object if it spans an even number of hard regs.
    4165              :          This special case is important for SCmode on 64-bit platforms
    4166              :          where the natural size of floating-point regs is 32-bit.  */
    4167        20842 :       || (REG_P (cplx)
    4168          338 :           && REGNO (cplx) < FIRST_PSEUDO_REGISTER
    4169          292 :           && REG_NREGS (cplx) % 2 == 0))
    4170              :     {
    4171        10229 :       rtx ret = simplify_gen_subreg (imode, cplx, cmode,
    4172        15343 :                                      imag_p ? GET_MODE_SIZE (imode) : 0);
    4173        10229 :       if (ret)
    4174              :         return ret;
    4175              :       else
    4176              :         /* simplify_gen_subreg may fail for sub-word MEMs.  */
    4177            0 :         gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
    4178              :     }
    4179              : 
    4180        15917 :   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
    4181              :                             true, NULL_RTX, imode, imode, false, NULL);
    4182              : }
    4183              : 
    4184              : /* A subroutine of emit_move_insn_1.  Yet another lowpart generator.
    4185              :    NEW_MODE and OLD_MODE are the same size.  Return NULL if X cannot be
    4186              :    represented in NEW_MODE.  If FORCE is true, this will never happen, as
    4187              :    we'll force-create a SUBREG if needed.  */
    4188              : 
    4189              : static rtx
    4190       243052 : emit_move_change_mode (machine_mode new_mode,
    4191              :                        machine_mode old_mode, rtx x, bool force)
    4192              : {
    4193       243052 :   rtx ret;
    4194              : 
    4195       243052 :   if (push_operand (x, GET_MODE (x)))
    4196              :     {
    4197         1318 :       ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
    4198         1318 :       MEM_COPY_ATTRIBUTES (ret, x);
    4199              :     }
    4200       241734 :   else if (MEM_P (x))
    4201              :     {
    4202              :       /* We don't have to worry about changing the address since the
    4203              :          size in bytes is supposed to be the same.  */
    4204        52760 :       if (reload_in_progress)
    4205              :         {
    4206              :           /* Copy the MEM to change the mode and move any
    4207              :              substitutions from the old MEM to the new one.  */
    4208            0 :           ret = adjust_address_nv (x, new_mode, 0);
    4209            0 :           copy_replacements (x, ret);
    4210              :         }
    4211              :       else
    4212        52760 :         ret = adjust_address (x, new_mode, 0);
    4213              :     }
    4214              :   else
    4215              :     {
    4216              :       /* Note that we do want simplify_subreg's behavior of validating
    4217              :          that the new mode is ok for a hard register.  If we were to use
    4218              :          simplify_gen_subreg, we would create the subreg, but would
    4219              :          probably run into the target not being able to implement it.  */
    4220              :       /* Except, of course, when FORCE is true, when this is exactly what
    4221              :          we want.  Which is needed for CCmodes on some targets.  */
    4222       188974 :       if (force)
    4223       188974 :         ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
    4224              :       else
    4225            0 :         ret = simplify_subreg (new_mode, x, old_mode, 0);
    4226              :     }
    4227              : 
    4228       243052 :   return ret;
    4229              : }
    4230              : 
    4231              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X using
    4232              :    an integer mode of the same size as MODE.  Returns the instruction
    4233              :    emitted, or NULL if such a move could not be generated.  */
    4234              : 
    4235              : static rtx_insn *
    4236       121526 : emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
    4237              : {
    4238       121526 :   scalar_int_mode imode;
    4239       121526 :   enum insn_code code;
    4240              : 
    4241              :   /* There must exist a mode of the exact size we require.  */
    4242       121526 :   if (!int_mode_for_mode (mode).exists (&imode))
    4243            0 :     return NULL;
    4244              : 
    4245              :   /* The target must support moves in this mode.  */
    4246       121526 :   code = optab_handler (mov_optab, imode);
    4247       121526 :   if (code == CODE_FOR_nothing)
    4248              :     return NULL;
    4249              : 
    4250       121526 :   x = emit_move_change_mode (imode, mode, x, force);
    4251       121526 :   if (x == NULL_RTX)
    4252              :     return NULL;
    4253       121526 :   y = emit_move_change_mode (imode, mode, y, force);
    4254       121526 :   if (y == NULL_RTX)
    4255              :     return NULL;
    4256       121526 :   return emit_insn (GEN_FCN (code) (x, y));
    4257              : }
    4258              : 
    4259              : /* A subroutine of emit_move_insn_1.  X is a push_operand in MODE.
    4260              :    Return an equivalent MEM that does not use an auto-increment.  */
    4261              : 
    4262              : rtx
    4263         3593 : emit_move_resolve_push (machine_mode mode, rtx x)
    4264              : {
    4265         3593 :   enum rtx_code code = GET_CODE (XEXP (x, 0));
    4266         3593 :   rtx temp;
    4267              : 
    4268         7186 :   poly_int64 adjust = GET_MODE_SIZE (mode);
    4269              : #ifdef PUSH_ROUNDING
    4270         3593 :   adjust = PUSH_ROUNDING (adjust);
    4271              : #endif
    4272         3593 :   if (code == PRE_DEC || code == POST_DEC)
    4273         3197 :     adjust = -adjust;
    4274          396 :   else if (code == PRE_MODIFY || code == POST_MODIFY)
    4275              :     {
    4276          396 :       rtx expr = XEXP (XEXP (x, 0), 1);
    4277              : 
    4278          396 :       gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
    4279          396 :       poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
    4280          396 :       if (GET_CODE (expr) == MINUS)
    4281            0 :         val = -val;
    4282          396 :       gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
    4283              :       adjust = val;
    4284              :     }
    4285              : 
    4286              :   /* Do not use anti_adjust_stack, since we don't want to update
    4287              :      stack_pointer_delta.  */
    4288         3597 :   temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
    4289         3593 :                               gen_int_mode (adjust, Pmode), stack_pointer_rtx,
    4290              :                               0, OPTAB_LIB_WIDEN);
    4291         3593 :   if (temp != stack_pointer_rtx)
    4292            0 :     emit_move_insn (stack_pointer_rtx, temp);
    4293              : 
    4294         3593 :   switch (code)
    4295              :     {
    4296         3593 :     case PRE_INC:
    4297         3593 :     case PRE_DEC:
    4298         3593 :     case PRE_MODIFY:
    4299         3593 :       temp = stack_pointer_rtx;
    4300         3593 :       break;
    4301              :     case POST_INC:
    4302              :     case POST_DEC:
    4303              :     case POST_MODIFY:
    4304            0 :       temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
    4305            0 :       break;
    4306            0 :     default:
    4307            0 :       gcc_unreachable ();
    4308              :     }
    4309              : 
    4310         3593 :   return replace_equiv_address (x, temp);
    4311              : }
    4312              : 
    4313              : /* A subroutine of emit_move_complex.  Generate a move from Y into X.
    4314              :    X is known to satisfy push_operand, and MODE is known to be complex.
    4315              :    Returns the last instruction emitted.  */
    4316              : 
    4317              : rtx_insn *
    4318         5379 : emit_move_complex_push (machine_mode mode, rtx x, rtx y)
    4319              : {
    4320         5379 :   scalar_mode submode = GET_MODE_INNER (mode);
    4321         5379 :   bool imag_first;
    4322              : 
    4323              : #ifdef PUSH_ROUNDING
    4324        10758 :   poly_int64 submodesize = GET_MODE_SIZE (submode);
    4325              : 
    4326              :   /* In case we output to the stack, but the size is smaller than the
    4327              :      machine can push exactly, we need to use move instructions.  */
    4328         5379 :   if (maybe_ne (PUSH_ROUNDING (submodesize), submodesize))
    4329              :     {
    4330          718 :       x = emit_move_resolve_push (mode, x);
    4331          718 :       return emit_move_insn (x, y);
    4332              :     }
    4333              : #endif
    4334              : 
    4335              :   /* Note that the real part always precedes the imag part in memory
    4336              :      regardless of machine's endianness.  */
    4337         4661 :   switch (GET_CODE (XEXP (x, 0)))
    4338              :     {
    4339              :     case PRE_DEC:
    4340              :     case POST_DEC:
    4341              :       imag_first = true;
    4342              :       break;
    4343            0 :     case PRE_INC:
    4344            0 :     case POST_INC:
    4345            0 :       imag_first = false;
    4346            0 :       break;
    4347            0 :     default:
    4348            0 :       gcc_unreachable ();
    4349              :     }
    4350              : 
    4351         4661 :   emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
    4352              :                   read_complex_part (y, imag_first));
    4353         4661 :   return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
    4354         9322 :                          read_complex_part (y, !imag_first));
    4355              : }
    4356              : 
    4357              : /* A subroutine of emit_move_complex.  Perform the move from Y to X
    4358              :    via two moves of the parts.  Returns the last instruction emitted.  */
    4359              : 
    4360              : rtx_insn *
    4361        73270 : emit_move_complex_parts (rtx x, rtx y)
    4362              : {
    4363              :   /* Show the output dies here.  This is necessary for SUBREGs
    4364              :      of pseudos since we cannot track their lifetimes correctly;
    4365              :      hard regs shouldn't appear here except as return values.  */
    4366        73270 :   if (!reload_completed && !reload_in_progress
    4367       146540 :       && REG_P (x) && !reg_overlap_mentioned_p (x, y))
    4368         6121 :     emit_clobber (x);
    4369              : 
    4370        73270 :   write_complex_part (x, read_complex_part (y, false), false, true);
    4371        73270 :   write_complex_part (x, read_complex_part (y, true), true, false);
    4372              : 
    4373        73270 :   return get_last_insn ();
    4374              : }
    4375              : 
    4376              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4377              :    MODE is known to be complex.  Returns the last instruction emitted.  */
    4378              : 
    4379              : static rtx_insn *
    4380        78005 : emit_move_complex (machine_mode mode, rtx x, rtx y)
    4381              : {
    4382        78005 :   bool try_int;
    4383              : 
    4384              :   /* Need to take special care for pushes, to maintain proper ordering
    4385              :      of the data, and possibly extra padding.  */
    4386        78005 :   if (push_operand (x, mode))
    4387         4771 :     return emit_move_complex_push (mode, x, y);
    4388              : 
    4389              :   /* See if we can coerce the target into moving both values at once, except
    4390              :      for floating point where we favor moving as parts if this is easy.  */
    4391        73234 :   if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
    4392        65019 :       && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
    4393        65019 :       && !(REG_P (x)
    4394         2214 :            && HARD_REGISTER_P (x)
    4395          564 :            && REG_NREGS (x) == 1)
    4396       138253 :       && !(REG_P (y)
    4397         3304 :            && HARD_REGISTER_P (y)
    4398         1652 :            && REG_NREGS (y) == 1))
    4399              :     try_int = false;
    4400              :   /* Not possible if the values are inherently not adjacent.  */
    4401         8215 :   else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
    4402              :     try_int = false;
    4403              :   /* Is possible if both are registers (or subregs of registers).  */
    4404          757 :   else if (register_operand (x, mode) && register_operand (y, mode))
    4405              :     try_int = true;
    4406              :   /* If one of the operands is a memory, and alignment constraints
    4407              :      are friendly enough, we may be able to do combined memory operations.
    4408              :      We do not attempt this if Y is a constant because that combination is
    4409              :      usually better with the by-parts thing below.  */
    4410          635 :   else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
    4411              :            && (!STRICT_ALIGNMENT
    4412              :                || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
    4413              :     try_int = true;
    4414              :   else
    4415              :     try_int = false;
    4416              : 
    4417              :   if (try_int)
    4418              :     {
    4419          757 :       rtx_insn *ret;
    4420              : 
    4421              :       /* For memory to memory moves, optimal behavior can be had with the
    4422              :          existing block move logic.  But use normal expansion if optimizing
    4423              :          for size.  */
    4424          757 :       if (MEM_P (x) && MEM_P (y))
    4425              :         {
    4426          726 :           emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
    4427          360 :                            (optimize_insn_for_speed_p()
    4428              :                             ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
    4429          360 :           return get_last_insn ();
    4430              :         }
    4431              : 
    4432          397 :       ret = emit_move_via_integer (mode, x, y, true);
    4433          397 :       if (ret)
    4434              :         return ret;
    4435              :     }
    4436              : 
    4437        72477 :   return emit_move_complex_parts (x, y);
    4438              : }
    4439              : 
    4440              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4441              :    MODE is known to be MODE_CC.  Returns the last instruction emitted.  */
    4442              : 
    4443              : static rtx_insn *
    4444            0 : emit_move_ccmode (machine_mode mode, rtx x, rtx y)
    4445              : {
    4446            0 :   rtx_insn *ret;
    4447              : 
    4448              :   /* Assume all MODE_CC modes are equivalent; if we have movcc, use it.  */
    4449            0 :   if (mode != CCmode)
    4450              :     {
    4451            0 :       enum insn_code code = optab_handler (mov_optab, CCmode);
    4452            0 :       if (code != CODE_FOR_nothing)
    4453              :         {
    4454            0 :           x = emit_move_change_mode (CCmode, mode, x, true);
    4455            0 :           y = emit_move_change_mode (CCmode, mode, y, true);
    4456            0 :           return emit_insn (GEN_FCN (code) (x, y));
    4457              :         }
    4458              :     }
    4459              : 
    4460              :   /* Otherwise, find the MODE_INT mode of the same width.  */
    4461            0 :   ret = emit_move_via_integer (mode, x, y, false);
    4462            0 :   gcc_assert (ret != NULL);
    4463              :   return ret;
    4464              : }
    4465              : 
    4466              : /* Return true if word I of OP lies entirely in the
    4467              :    undefined bits of a paradoxical subreg.  */
    4468              : 
    4469              : static bool
    4470            0 : undefined_operand_subword_p (const_rtx op, int i)
    4471              : {
    4472            0 :   if (GET_CODE (op) != SUBREG)
    4473              :     return false;
    4474            0 :   machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    4475            0 :   poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
    4476            0 :   return (known_ge (offset, GET_MODE_SIZE (innermostmode))
    4477            0 :           || known_le (offset, -UNITS_PER_WORD));
    4478              : }
    4479              : 
    4480              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4481              :    MODE is any multi-word or full-word mode that lacks a move_insn
    4482              :    pattern.  Note that you will get better code if you define such
    4483              :    patterns, even if they must turn into multiple assembler instructions.  */
    4484              : 
    4485              : static rtx_insn *
    4486            0 : emit_move_multi_word (machine_mode mode, rtx x, rtx y)
    4487              : {
    4488            0 :   rtx_insn *last_insn = 0;
    4489            0 :   rtx_insn *seq;
    4490            0 :   rtx inner;
    4491            0 :   bool need_clobber;
    4492            0 :   int i, mode_size;
    4493              : 
    4494              :   /* This function can only handle cases where the number of words is
    4495              :      known at compile time.  */
    4496            0 :   mode_size = GET_MODE_SIZE (mode).to_constant ();
    4497            0 :   gcc_assert (mode_size >= UNITS_PER_WORD);
    4498              : 
    4499              :   /* If X is a push on the stack, do the push now and replace
    4500              :      X with a reference to the stack pointer.  */
    4501            0 :   if (push_operand (x, mode))
    4502            0 :     x = emit_move_resolve_push (mode, x);
    4503              : 
    4504              :   /* If we are in reload, see if either operand is a MEM whose address
    4505              :      is scheduled for replacement.  */
    4506            0 :   if (reload_in_progress && MEM_P (x)
    4507            0 :       && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
    4508            0 :     x = replace_equiv_address_nv (x, inner);
    4509            0 :   if (reload_in_progress && MEM_P (y)
    4510            0 :       && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
    4511            0 :     y = replace_equiv_address_nv (y, inner);
    4512              : 
    4513            0 :   start_sequence ();
    4514              : 
    4515            0 :   need_clobber = false;
    4516            0 :   for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
    4517              :     {
    4518              :       /* Do not generate code for a move if it would go entirely
    4519              :          to the non-existing bits of a paradoxical subreg.  */
    4520            0 :       if (undefined_operand_subword_p (x, i))
    4521            0 :         continue;
    4522              : 
    4523            0 :       rtx xpart = operand_subword (x, i, 1, mode);
    4524            0 :       rtx ypart;
    4525              : 
    4526              :       /* Do not generate code for a move if it would come entirely
    4527              :          from the undefined bits of a paradoxical subreg.  */
    4528            0 :       if (undefined_operand_subword_p (y, i))
    4529            0 :         continue;
    4530              : 
    4531            0 :       ypart = operand_subword (y, i, 1, mode);
    4532              : 
    4533              :       /* If we can't get a part of Y, put Y into memory if it is a
    4534              :          constant.  Otherwise, force it into a register.  Then we must
    4535              :          be able to get a part of Y.  */
    4536            0 :       if (ypart == 0 && CONSTANT_P (y))
    4537              :         {
    4538            0 :           y = use_anchored_address (force_const_mem (mode, y));
    4539            0 :           ypart = operand_subword (y, i, 1, mode);
    4540              :         }
    4541            0 :       else if (ypart == 0)
    4542            0 :         ypart = operand_subword_force (y, i, mode);
    4543              : 
    4544            0 :       gcc_assert (xpart && ypart);
    4545              : 
    4546            0 :       need_clobber |= (GET_CODE (xpart) == SUBREG);
    4547              : 
    4548            0 :       last_insn = emit_move_insn (xpart, ypart);
    4549              :     }
    4550              : 
    4551            0 :   seq = end_sequence ();
    4552              : 
    4553              :   /* Show the output dies here.  This is necessary for SUBREGs
    4554              :      of pseudos since we cannot track their lifetimes correctly;
    4555              :      hard regs shouldn't appear here except as return values.
    4556              :      We never want to emit such a clobber after reload.  */
    4557            0 :   if (x != y
    4558            0 :       && ! (reload_in_progress || reload_completed)
    4559            0 :       && need_clobber != 0)
    4560            0 :     emit_clobber (x);
    4561              : 
    4562            0 :   emit_insn (seq);
    4563              : 
    4564            0 :   return last_insn;
    4565              : }
    4566              : 
    4567              : /* Low level part of emit_move_insn.
    4568              :    Called just like emit_move_insn, but assumes X and Y
    4569              :    are basically valid.  */
    4570              : 
    4571              : rtx_insn *
    4572     75619367 : emit_move_insn_1 (rtx x, rtx y)
    4573              : {
    4574     75619367 :   machine_mode mode = GET_MODE (x);
    4575     75619367 :   enum insn_code code;
    4576              : 
    4577     75619367 :   gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
    4578              : 
    4579     75619367 :   code = optab_handler (mov_optab, mode);
    4580     75619367 :   if (code != CODE_FOR_nothing)
    4581     75420233 :     return emit_insn (GEN_FCN (code) (x, y));
    4582              : 
    4583              :   /* Expand complex moves by moving real part and imag part.  */
    4584       199134 :   if (COMPLEX_MODE_P (mode))
    4585        78005 :     return emit_move_complex (mode, x, y);
    4586              : 
    4587              :   if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
    4588              :       || ALL_FIXED_POINT_MODE_P (mode))
    4589              :     {
    4590       121129 :       rtx_insn *result = emit_move_via_integer (mode, x, y, true);
    4591              : 
    4592              :       /* If we can't find an integer mode, use multi words.  */
    4593       121129 :       if (result)
    4594              :         return result;
    4595              :       else
    4596            0 :         return emit_move_multi_word (mode, x, y);
    4597              :     }
    4598              : 
    4599              :   if (GET_MODE_CLASS (mode) == MODE_CC)
    4600            0 :     return emit_move_ccmode (mode, x, y);
    4601              : 
    4602              :   /* Try using a move pattern for the corresponding integer mode.  This is
    4603              :      only safe when simplify_subreg can convert MODE constants into integer
    4604              :      constants.  At present, it can only do this reliably if the value
    4605              :      fits within a HOST_WIDE_INT.  */
    4606            0 :   if (!CONSTANT_P (y)
    4607            0 :       || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
    4608              :     {
    4609            0 :       rtx_insn *ret = emit_move_via_integer (mode, x, y, lra_in_progress);
    4610              : 
    4611            0 :       if (ret)
    4612              :         {
    4613            0 :           if (! lra_in_progress || recog (PATTERN (ret), ret, 0) >= 0)
    4614            0 :             return ret;
    4615              :         }
    4616              :     }
    4617              : 
    4618            0 :   return emit_move_multi_word (mode, x, y);
    4619              : }
    4620              : 
    4621              : /* Generate code to copy Y into X.
    4622              :    Both Y and X must have the same mode, except that
    4623              :    Y can be a constant with VOIDmode.
    4624              :    This mode cannot be BLKmode; use emit_block_move for that.
    4625              : 
    4626              :    Return the last instruction emitted.  */
    4627              : 
    4628              : rtx_insn *
    4629     69761558 : emit_move_insn (rtx x, rtx y)
    4630              : {
    4631     69761558 :   machine_mode mode = GET_MODE (x);
    4632     69761558 :   rtx y_cst = NULL_RTX;
    4633     69761558 :   rtx_insn *last_insn;
    4634     69761558 :   rtx set;
    4635              : 
    4636     69761558 :   gcc_assert (mode != BLKmode
    4637              :               && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
    4638              : 
    4639              :   /* If we have a copy that looks like one of the following patterns:
    4640              :        (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
    4641              :        (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
    4642              :        (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
    4643              :        (set (subreg:M1 (reg:M2 ...)) (constant C))
    4644              :      where mode M1 is equal in size to M2, try to detect whether the
    4645              :      mode change involves an implicit round trip through memory.
    4646              :      If so, see if we can avoid that by removing the subregs and
    4647              :      doing the move in mode M2 instead.  */
    4648              : 
    4649     69761558 :   rtx x_inner = NULL_RTX;
    4650     69761558 :   rtx y_inner = NULL_RTX;
    4651              : 
    4652     72400980 :   auto candidate_subreg_p = [&](rtx subreg) {
    4653      2639422 :     return (REG_P (SUBREG_REG (subreg))
    4654      7916529 :             && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
    4655              :                          GET_MODE_SIZE (GET_MODE (subreg)))
    4656      2954774 :             && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg)))
    4657      2639422 :                != CODE_FOR_nothing);
    4658              :   };
    4659              : 
    4660     69767651 :   auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
    4661         6093 :     return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
    4662         6093 :             && !push_operand (mem, GET_MODE (mem))
    4663              :             /* Not a candiate if innermode requires too much alignment.  */
    4664        12126 :             && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
    4665          224 :                 || targetm.slow_unaligned_access (GET_MODE (mem),
    4666          112 :                                                   MEM_ALIGN (mem))
    4667          224 :                 || !targetm.slow_unaligned_access (innermode,
    4668          112 :                                                    MEM_ALIGN (mem))));
    4669              :   };
    4670              : 
    4671     69761558 :   if (SUBREG_P (x) && candidate_subreg_p (x))
    4672        11075 :     x_inner = SUBREG_REG (x);
    4673              : 
    4674     69761558 :   if (SUBREG_P (y) && candidate_subreg_p (y))
    4675       302947 :     y_inner = SUBREG_REG (y);
    4676              : 
    4677     69761558 :   if (x_inner != NULL_RTX
    4678     69761558 :       && y_inner != NULL_RTX
    4679         1093 :       && GET_MODE (x_inner) == GET_MODE (y_inner)
    4680     69762246 :       && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
    4681              :     {
    4682          688 :       x = x_inner;
    4683          688 :       y = y_inner;
    4684          688 :       mode = GET_MODE (x_inner);
    4685              :     }
    4686     69760870 :   else if (x_inner != NULL_RTX
    4687        10387 :            && MEM_P (y)
    4688     69761184 :            && candidate_mem_p (GET_MODE (x_inner), y))
    4689              :     {
    4690          314 :       x = x_inner;
    4691          314 :       y = adjust_address (y, GET_MODE (x_inner), 0);
    4692          314 :       mode = GET_MODE (x_inner);
    4693              :     }
    4694     69760556 :   else if (y_inner != NULL_RTX
    4695       302259 :            && MEM_P (x)
    4696     69766335 :            && candidate_mem_p (GET_MODE (y_inner), x))
    4697              :     {
    4698         5719 :       x = adjust_address (x, GET_MODE (y_inner), 0);
    4699         5719 :       y = y_inner;
    4700         5719 :       mode = GET_MODE (y_inner);
    4701              :     }
    4702     69754837 :   else if (x_inner != NULL_RTX
    4703        10073 :            && CONSTANT_P (y)
    4704          470 :            && !targetm.can_change_mode_class (GET_MODE (x_inner),
    4705              :                                               mode, ALL_REGS)
    4706     69755307 :            && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
    4707              :     {
    4708          470 :       x = x_inner;
    4709          470 :       y = y_inner;
    4710          470 :       mode = GET_MODE (x_inner);
    4711              :     }
    4712              : 
    4713     69761558 :   if (CONSTANT_P (y))
    4714              :     {
    4715     16315981 :       if (optimize
    4716     12736626 :           && SCALAR_FLOAT_MODE_P (GET_MODE (x))
    4717     17081802 :           && (last_insn = compress_float_constant (x, y)))
    4718              :         return last_insn;
    4719              : 
    4720     16247280 :       y_cst = y;
    4721              : 
    4722     16247280 :       if (!targetm.legitimate_constant_p (mode, y))
    4723              :         {
    4724       497446 :           y = force_const_mem (mode, y);
    4725              : 
    4726              :           /* If the target's cannot_force_const_mem prevented the spill,
    4727              :              assume that the target's move expanders will also take care
    4728              :              of the non-legitimate constant.  */
    4729       497446 :           if (!y)
    4730              :             y = y_cst;
    4731              :           else
    4732       477400 :             y = use_anchored_address (y);
    4733              :         }
    4734              :     }
    4735              : 
    4736              :   /* If X or Y are memory references, verify that their addresses are valid
    4737              :      for the machine.  */
    4738     69692857 :   if (MEM_P (x)
    4739     85695973 :       && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
    4740     13752302 :                                          MEM_ADDR_SPACE (x))
    4741      2250988 :           && ! push_operand (x, GET_MODE (x))))
    4742          174 :     x = validize_mem (x);
    4743              : 
    4744     69692857 :   if (MEM_P (y)
    4745     87369984 :       && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
    4746     17677127 :                                         MEM_ADDR_SPACE (y)))
    4747         9376 :     y = validize_mem (y);
    4748              : 
    4749     69692857 :   gcc_assert (mode != BLKmode);
    4750              : 
    4751     69692857 :   last_insn = emit_move_insn_1 (x, y);
    4752              : 
    4753     16247280 :   if (y_cst && REG_P (x)
    4754     11923461 :       && (set = single_set (last_insn)) != NULL_RTX
    4755     11923461 :       && SET_DEST (set) == x
    4756     81601867 :       && ! rtx_equal_p (y_cst, SET_SRC (set)))
    4757      1226161 :     set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
    4758              : 
    4759              :   return last_insn;
    4760              : }
    4761              : 
    4762              : /* Generate the body of an instruction to copy Y into X.
    4763              :    It may be a list of insns, if one insn isn't enough.  */
    4764              : 
    4765              : rtx_insn *
    4766      5926430 : gen_move_insn (rtx x, rtx y)
    4767              : {
    4768      5926430 :   start_sequence ();
    4769      5926430 :   emit_move_insn_1 (x, y);
    4770      5926430 :   return end_sequence ();
    4771              : }
    4772              : 
    4773              : /* If Y is representable exactly in a narrower mode, and the target can
    4774              :    perform the extension directly from constant or memory, then emit the
    4775              :    move as an extension.  */
    4776              : 
    4777              : static rtx_insn *
    4778       765821 : compress_float_constant (rtx x, rtx y)
    4779              : {
    4780       765821 :   machine_mode dstmode = GET_MODE (x);
    4781       765821 :   machine_mode orig_srcmode = GET_MODE (y);
    4782       765821 :   machine_mode srcmode;
    4783       765821 :   const REAL_VALUE_TYPE *r;
    4784       765821 :   int oldcost, newcost;
    4785       765821 :   bool speed = optimize_insn_for_speed_p ();
    4786              : 
    4787       765821 :   r = CONST_DOUBLE_REAL_VALUE (y);
    4788              : 
    4789       765821 :   if (targetm.legitimate_constant_p (dstmode, y))
    4790       764207 :     oldcost = set_src_cost (y, orig_srcmode, speed);
    4791              :   else
    4792         1614 :     oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
    4793              : 
    4794      2714749 :   FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
    4795              :     {
    4796      2017629 :       enum insn_code ic;
    4797      2017629 :       rtx trunc_y;
    4798      2017629 :       rtx_insn *last_insn;
    4799              : 
    4800              :       /* Skip if the target can't extend this way.  */
    4801      2017629 :       ic = can_extend_p (dstmode, srcmode, 0);
    4802      2017629 :       if (ic == CODE_FOR_nothing)
    4803      1597196 :         continue;
    4804              : 
    4805              :       /* Skip if the narrowed value isn't exact.  */
    4806       420433 :       if (! exact_real_truncate (srcmode, r))
    4807        51418 :         continue;
    4808              : 
    4809       369015 :       trunc_y = const_double_from_real_value (*r, srcmode);
    4810              : 
    4811       369015 :       if (targetm.legitimate_constant_p (srcmode, trunc_y))
    4812              :         {
    4813              :           /* Skip if the target needs extra instructions to perform
    4814              :              the extension.  */
    4815       364932 :           if (!insn_operand_matches (ic, 1, trunc_y))
    4816         4078 :             continue;
    4817              :           /* This is valid, but may not be cheaper than the original. */
    4818       360854 :           newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
    4819              :                                   dstmode, speed);
    4820       360854 :           if (oldcost < newcost)
    4821       292153 :             continue;
    4822              :         }
    4823         4083 :       else if (float_extend_from_mem[dstmode][srcmode])
    4824              :         {
    4825            0 :           trunc_y = force_const_mem (srcmode, trunc_y);
    4826              :           /* This is valid, but may not be cheaper than the original. */
    4827            0 :           newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
    4828              :                                   dstmode, speed);
    4829            0 :           if (oldcost < newcost)
    4830            0 :             continue;
    4831            0 :           trunc_y = validize_mem (trunc_y);
    4832              :         }
    4833              :       else
    4834         4083 :         continue;
    4835              : 
    4836              :       /* For CSE's benefit, force the compressed constant pool entry
    4837              :          into a new pseudo.  This constant may be used in different modes,
    4838              :          and if not, combine will put things back together for us.  */
    4839        68701 :       trunc_y = force_reg (srcmode, trunc_y);
    4840              : 
    4841              :       /* If x is a hard register, perform the extension into a pseudo,
    4842              :          so that e.g. stack realignment code is aware of it.  */
    4843        68701 :       rtx target = x;
    4844        68701 :       if (REG_P (x) && HARD_REGISTER_P (x))
    4845            1 :         target = gen_reg_rtx (dstmode);
    4846              : 
    4847        68701 :       emit_unop_insn (ic, target, trunc_y, UNKNOWN);
    4848        68701 :       last_insn = get_last_insn ();
    4849              : 
    4850        68701 :       if (REG_P (target))
    4851        57820 :         set_unique_reg_note (last_insn, REG_EQUAL, y);
    4852              : 
    4853        68701 :       if (target != x)
    4854            1 :         return emit_move_insn (x, target);
    4855              :       return last_insn;
    4856              :     }
    4857              : 
    4858              :   return NULL;
    4859              : }
    4860              : 
    4861              : /* Pushing data onto the stack.  */
    4862              : 
    4863              : /* Push a block of length SIZE (perhaps variable)
    4864              :    and return an rtx to address the beginning of the block.
    4865              :    The value may be virtual_outgoing_args_rtx.
    4866              : 
    4867              :    EXTRA is the number of bytes of padding to push in addition to SIZE.
    4868              :    BELOW nonzero means this padding comes at low addresses;
    4869              :    otherwise, the padding comes at high addresses.  */
    4870              : 
    4871              : rtx
    4872       268136 : push_block (rtx size, poly_int64 extra, int below)
    4873              : {
    4874       268136 :   rtx temp;
    4875              : 
    4876       333329 :   size = convert_modes (Pmode, ptr_mode, size, 1);
    4877       268136 :   if (CONSTANT_P (size))
    4878       333329 :     anti_adjust_stack (plus_constant (Pmode, size, extra));
    4879            0 :   else if (REG_P (size) && known_eq (extra, 0))
    4880            0 :     anti_adjust_stack (size);
    4881              :   else
    4882              :     {
    4883            0 :       temp = copy_to_mode_reg (Pmode, size);
    4884            0 :       if (maybe_ne (extra, 0))
    4885            0 :         temp = expand_binop (Pmode, add_optab, temp,
    4886            0 :                              gen_int_mode (extra, Pmode),
    4887              :                              temp, 0, OPTAB_LIB_WIDEN);
    4888            0 :       anti_adjust_stack (temp);
    4889              :     }
    4890              : 
    4891       268136 :   if (STACK_GROWS_DOWNWARD)
    4892              :     {
    4893       268136 :       temp = virtual_outgoing_args_rtx;
    4894       268136 :       if (maybe_ne (extra, 0) && below)
    4895            0 :         temp = plus_constant (Pmode, temp, extra);
    4896              :     }
    4897              :   else
    4898              :     {
    4899              :       poly_int64 csize;
    4900              :       if (poly_int_rtx_p (size, &csize))
    4901              :         temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
    4902              :                               -csize - (below ? 0 : extra));
    4903              :       else if (maybe_ne (extra, 0) && !below)
    4904              :         temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
    4905              :                              negate_rtx (Pmode, plus_constant (Pmode, size,
    4906              :                                                                extra)));
    4907              :       else
    4908              :         temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
    4909              :                              negate_rtx (Pmode, size));
    4910              :     }
    4911              : 
    4912       268136 :   return memory_address (NARROWEST_INT_MODE, temp);
    4913              : }
    4914              : 
    4915              : /* A utility routine that returns the base of an auto-inc memory, or NULL.  */
    4916              : 
    4917              : static rtx
    4918      2574706 : mem_autoinc_base (rtx mem)
    4919              : {
    4920            0 :   if (MEM_P (mem))
    4921              :     {
    4922      1576761 :       rtx addr = XEXP (mem, 0);
    4923      1576761 :       if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
    4924      1029165 :         return XEXP (addr, 0);
    4925              :     }
    4926              :   return NULL;
    4927              : }
    4928              : 
    4929              : /* A utility routine used here, in reload, and in try_split.  The insns
    4930              :    after PREV up to and including LAST are known to adjust the stack,
    4931              :    with a final value of END_ARGS_SIZE.  Iterate backward from LAST
    4932              :    placing notes as appropriate.  PREV may be NULL, indicating the
    4933              :    entire insn sequence prior to LAST should be scanned.
    4934              : 
    4935              :    The set of allowed stack pointer modifications is small:
    4936              :      (1) One or more auto-inc style memory references (aka pushes),
    4937              :      (2) One or more addition/subtraction with the SP as destination,
    4938              :      (3) A single move insn with the SP as destination,
    4939              :      (4) A call_pop insn,
    4940              :      (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
    4941              : 
    4942              :    Insns in the sequence that do not modify the SP are ignored,
    4943              :    except for noreturn calls.
    4944              : 
    4945              :    The return value is the amount of adjustment that can be trivially
    4946              :    verified, via immediate operand or auto-inc.  If the adjustment
    4947              :    cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN.  */
    4948              : 
    4949              : poly_int64
    4950      4374464 : find_args_size_adjust (rtx_insn *insn)
    4951              : {
    4952      4374464 :   rtx dest, set, pat;
    4953      4374464 :   int i;
    4954              : 
    4955      4374464 :   pat = PATTERN (insn);
    4956      4374464 :   set = NULL;
    4957              : 
    4958              :   /* Look for a call_pop pattern.  */
    4959      4374464 :   if (CALL_P (insn))
    4960              :     {
    4961              :       /* We have to allow non-call_pop patterns for the case
    4962              :          of emit_single_push_insn of a TLS address.  */
    4963      2729058 :       if (GET_CODE (pat) != PARALLEL)
    4964      2714563 :         return 0;
    4965              : 
    4966              :       /* All call_pop have a stack pointer adjust in the parallel.
    4967              :          The call itself is always first, and the stack adjust is
    4968              :          usually last, so search from the end.  */
    4969        14495 :       for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
    4970              :         {
    4971        14495 :           set = XVECEXP (pat, 0, i);
    4972        14495 :           if (GET_CODE (set) != SET)
    4973            0 :             continue;
    4974        14495 :           dest = SET_DEST (set);
    4975        14495 :           if (dest == stack_pointer_rtx)
    4976              :             break;
    4977              :         }
    4978              :       /* We'd better have found the stack pointer adjust.  */
    4979        14495 :       if (i == 0)
    4980            0 :         return 0;
    4981              :       /* Fall through to process the extracted SET and DEST
    4982              :          as if it was a standalone insn.  */
    4983              :     }
    4984      1645406 :   else if (GET_CODE (pat) == SET)
    4985              :     set = pat;
    4986       256550 :   else if ((set = single_set (insn)) != NULL)
    4987              :     ;
    4988        46638 :   else if (GET_CODE (pat) == PARALLEL)
    4989              :     {
    4990              :       /* ??? Some older ports use a parallel with a stack adjust
    4991              :          and a store for a PUSH_ROUNDING pattern, rather than a
    4992              :          PRE/POST_MODIFY rtx.  Don't force them to update yet...  */
    4993              :       /* ??? See h8300 and m68k, pushqi1.  */
    4994            0 :       for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
    4995              :         {
    4996            0 :           set = XVECEXP (pat, 0, i);
    4997            0 :           if (GET_CODE (set) != SET)
    4998            0 :             continue;
    4999            0 :           dest = SET_DEST (set);
    5000            0 :           if (dest == stack_pointer_rtx)
    5001              :             break;
    5002              : 
    5003              :           /* We do not expect an auto-inc of the sp in the parallel.  */
    5004            0 :           gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
    5005            0 :           gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
    5006              :                                != stack_pointer_rtx);
    5007              :         }
    5008            0 :       if (i < 0)
    5009            0 :         return 0;
    5010              :     }
    5011              :   else
    5012        46638 :     return 0;
    5013              : 
    5014      1613263 :   dest = SET_DEST (set);
    5015              : 
    5016              :   /* Look for direct modifications of the stack pointer.  */
    5017      1613263 :   if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
    5018              :     {
    5019              :       /* Look for a trivial adjustment, otherwise assume nothing.  */
    5020              :       /* Note that the SPU restore_stack_block pattern refers to
    5021              :          the stack pointer in V4SImode.  Consider that non-trivial.  */
    5022       325910 :       poly_int64 offset;
    5023       325910 :       if (SCALAR_INT_MODE_P (GET_MODE (dest))
    5024       325910 :           && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
    5025       323487 :         return offset;
    5026              :       /* ??? Reload can generate no-op moves, which will be cleaned
    5027              :          up later.  Recognize it and continue searching.  */
    5028         2423 :       else if (rtx_equal_p (dest, SET_SRC (set)))
    5029            0 :         return 0;
    5030              :       else
    5031         2423 :         return HOST_WIDE_INT_MIN;
    5032              :     }
    5033              :   else
    5034              :     {
    5035      1287353 :       rtx mem, addr;
    5036              : 
    5037              :       /* Otherwise only think about autoinc patterns.  */
    5038      2329304 :       if (mem_autoinc_base (dest) == stack_pointer_rtx)
    5039              :         {
    5040       920544 :           mem = dest;
    5041      1278327 :           gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
    5042              :                                != stack_pointer_rtx);
    5043              :         }
    5044       543836 :       else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
    5045              :         mem = SET_SRC (set);
    5046              :       else
    5047       258188 :         return 0;
    5048              : 
    5049      1029165 :       addr = XEXP (mem, 0);
    5050      1029165 :       switch (GET_CODE (addr))
    5051              :         {
    5052       108621 :         case PRE_INC:
    5053       108621 :         case POST_INC:
    5054       217242 :           return GET_MODE_SIZE (GET_MODE (mem));
    5055       902554 :         case PRE_DEC:
    5056       902554 :         case POST_DEC:
    5057      1805108 :           return -GET_MODE_SIZE (GET_MODE (mem));
    5058        17990 :         case PRE_MODIFY:
    5059        17990 :         case POST_MODIFY:
    5060        17990 :           addr = XEXP (addr, 1);
    5061        17990 :           gcc_assert (GET_CODE (addr) == PLUS);
    5062        17990 :           gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
    5063        17990 :           return rtx_to_poly_int64 (XEXP (addr, 1));
    5064            0 :         default:
    5065            0 :           gcc_unreachable ();
    5066              :         }
    5067              :     }
    5068              : }
    5069              : 
    5070              : poly_int64
    5071       664092 : fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
    5072              :                        poly_int64 end_args_size)
    5073              : {
    5074       664092 :   poly_int64 args_size = end_args_size;
    5075       664092 :   bool saw_unknown = false;
    5076       664092 :   rtx_insn *insn;
    5077              : 
    5078      1895715 :   for (insn = last; insn != prev; insn = PREV_INSN (insn))
    5079              :     {
    5080      1231623 :       if (!NONDEBUG_INSN_P (insn))
    5081            0 :         continue;
    5082              : 
    5083              :       /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
    5084              :          a call argument containing a TLS address that itself requires
    5085              :          a call to __tls_get_addr.  The handling of stack_pointer_delta
    5086              :          in emit_single_push_insn is supposed to ensure that any such
    5087              :          notes are already correct.  */
    5088      1231623 :       rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
    5089      1231623 :       gcc_assert (!note || known_eq (args_size, get_args_size (note)));
    5090              : 
    5091      1231623 :       poly_int64 this_delta = find_args_size_adjust (insn);
    5092      1231623 :       if (known_eq (this_delta, 0))
    5093              :         {
    5094       605833 :           if (!CALL_P (insn)
    5095            9 :               || ACCUMULATE_OUTGOING_ARGS
    5096       302930 :               || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
    5097       302912 :             continue;
    5098              :         }
    5099              : 
    5100       928711 :       gcc_assert (!saw_unknown);
    5101       928711 :       if (known_eq (this_delta, HOST_WIDE_INT_MIN))
    5102         2401 :         saw_unknown = true;
    5103              : 
    5104       928711 :       if (!note)
    5105       928711 :         add_args_size_note (insn, args_size);
    5106              :       if (STACK_GROWS_DOWNWARD)
    5107       928711 :         this_delta = -poly_uint64 (this_delta);
    5108              : 
    5109       928711 :       if (saw_unknown)
    5110              :         args_size = HOST_WIDE_INT_MIN;
    5111              :       else
    5112      1231623 :         args_size -= this_delta;
    5113              :     }
    5114              : 
    5115       664092 :   return args_size;
    5116              : }
    5117              : 
    5118              : #ifdef PUSH_ROUNDING
    5119              : /* Emit single push insn.  */
    5120              : 
    5121              : static void
    5122      1836824 : emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
    5123              : {
    5124      1836824 :   rtx dest_addr;
    5125      3673648 :   poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
    5126      1836824 :   rtx dest;
    5127      1836824 :   enum insn_code icode;
    5128              : 
    5129              :   /* If there is push pattern, use it.  Otherwise try old way of throwing
    5130              :      MEM representing push operation to move expander.  */
    5131      1836824 :   icode = optab_handler (push_optab, mode);
    5132      1836824 :   if (icode != CODE_FOR_nothing)
    5133              :     {
    5134            0 :       class expand_operand ops[1];
    5135              : 
    5136            0 :       create_input_operand (&ops[0], x, mode);
    5137            0 :       if (maybe_expand_insn (icode, 1, ops))
    5138            0 :         return;
    5139              :     }
    5140      3673648 :   if (known_eq (GET_MODE_SIZE (mode), rounded_size))
    5141      3174774 :     dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
    5142              :   /* If we are to pad downward, adjust the stack pointer first and
    5143              :      then store X into the stack location using an offset.  This is
    5144              :      because emit_move_insn does not know how to pad; it does not have
    5145              :      access to type.  */
    5146       103414 :   else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
    5147              :     {
    5148            0 :       emit_move_insn (stack_pointer_rtx,
    5149            0 :                       expand_binop (Pmode,
    5150              :                                     STACK_GROWS_DOWNWARD ? sub_optab
    5151              :                                     : add_optab,
    5152              :                                     stack_pointer_rtx,
    5153            0 :                                     gen_int_mode (rounded_size, Pmode),
    5154              :                                     NULL_RTX, 0, OPTAB_LIB_WIDEN));
    5155              : 
    5156            0 :       poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
    5157            0 :       if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
    5158              :         /* We have already decremented the stack pointer, so get the
    5159              :            previous value.  */
    5160              :         offset += rounded_size;
    5161              : 
    5162            0 :       if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
    5163              :         /* We have already incremented the stack pointer, so get the
    5164              :            previous value.  */
    5165              :         offset -= rounded_size;
    5166              : 
    5167            0 :       dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
    5168              :     }
    5169              :   else
    5170              :     {
    5171              :       if (STACK_GROWS_DOWNWARD)
    5172              :         /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
    5173       103966 :         dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    5174              :       else
    5175              :         /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
    5176              :         dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
    5177              : 
    5178       103966 :       dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
    5179              :     }
    5180              : 
    5181      1836824 :   dest = gen_rtx_MEM (mode, dest_addr);
    5182              : 
    5183      1836824 :   if (type != 0)
    5184              :     {
    5185      1836777 :       set_mem_attributes (dest, type, 1);
    5186              : 
    5187      1836777 :       if (cfun->tail_call_marked)
    5188              :         /* Function incoming arguments may overlap with sibling call
    5189              :            outgoing arguments and we cannot allow reordering of reads
    5190              :            from function arguments with stores to outgoing arguments
    5191              :            of sibling calls.  */
    5192       140476 :         set_mem_alias_set (dest, 0);
    5193              :     }
    5194      1836824 :   emit_move_insn (dest, x);
    5195              : }
    5196              : 
    5197              : /* Emit and annotate a single push insn.  */
    5198              : 
    5199              : static void
    5200      1836824 : emit_single_push_insn (machine_mode mode, rtx x, tree type)
    5201              : {
    5202      1836824 :   poly_int64 delta, old_delta = stack_pointer_delta;
    5203      1836824 :   rtx_insn *prev = get_last_insn ();
    5204      1836824 :   rtx_insn *last;
    5205              : 
    5206      1836824 :   emit_single_push_insn_1 (mode, x, type);
    5207              : 
    5208              :   /* Adjust stack_pointer_delta to describe the situation after the push
    5209              :      we just performed.  Note that we must do this after the push rather
    5210              :      than before the push in case calculating X needs pushes and pops of
    5211              :      its own (e.g. if calling __tls_get_addr).  The REG_ARGS_SIZE notes
    5212              :      for such pushes and pops must not include the effect of the future
    5213              :      push of X.  */
    5214      3673648 :   stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
    5215              : 
    5216      1836824 :   last = get_last_insn ();
    5217              : 
    5218              :   /* Notice the common case where we emitted exactly one insn.  */
    5219      1836824 :   if (PREV_INSN (last) == prev)
    5220              :     {
    5221      1726847 :       add_args_size_note (last, stack_pointer_delta);
    5222      1726847 :       return;
    5223              :     }
    5224              : 
    5225       109977 :   delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
    5226       109977 :   gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
    5227              :               || known_eq (delta, old_delta));
    5228              : }
    5229              : #endif
    5230              : 
    5231              : /* If reading SIZE bytes from X will end up reading from
    5232              :    Y return the number of bytes that overlap.  Return -1
    5233              :    if there is no overlap or -2 if we can't determine
    5234              :    (for example when X and Y have different base registers).  */
    5235              : 
    5236              : static int
    5237            0 : memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
    5238              : {
    5239            0 :   rtx tmp = plus_constant (Pmode, x, size);
    5240            0 :   rtx sub = simplify_gen_binary (MINUS, Pmode, tmp, y);
    5241              : 
    5242            0 :   if (!CONST_INT_P (sub))
    5243              :     return -2;
    5244              : 
    5245            0 :   HOST_WIDE_INT val = INTVAL (sub);
    5246              : 
    5247            0 :   return IN_RANGE (val, 1, size) ? val : -1;
    5248              : }
    5249              : 
    5250              : /* Generate code to push X onto the stack, assuming it has mode MODE and
    5251              :    type TYPE.
    5252              :    MODE is redundant except when X is a CONST_INT (since they don't
    5253              :    carry mode info).
    5254              :    SIZE is an rtx for the size of data to be copied (in bytes),
    5255              :    needed only if X is BLKmode.
    5256              :    Return true if successful.  May return false if asked to push a
    5257              :    partial argument during a sibcall optimization (as specified by
    5258              :    SIBCALL_P) and the incoming and outgoing pointers cannot be shown
    5259              :    to not overlap.
    5260              : 
    5261              :    ALIGN (in bits) is maximum alignment we can assume.
    5262              : 
    5263              :    If PARTIAL and REG are both nonzero, then copy that many of the first
    5264              :    bytes of X into registers starting with REG, and push the rest of X.
    5265              :    The amount of space pushed is decreased by PARTIAL bytes.
    5266              :    REG must be a hard register in this case.
    5267              :    If REG is zero but PARTIAL is not, take any all others actions for an
    5268              :    argument partially in registers, but do not actually load any
    5269              :    registers.
    5270              : 
    5271              :    EXTRA is the amount in bytes of extra space to leave next to this arg.
    5272              :    This is ignored if an argument block has already been allocated.
    5273              : 
    5274              :    On a machine that lacks real push insns, ARGS_ADDR is the address of
    5275              :    the bottom of the argument block for this call.  We use indexing off there
    5276              :    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
    5277              :    argument block has not been preallocated.
    5278              : 
    5279              :    ARGS_SO_FAR is the size of args previously pushed for this call.
    5280              : 
    5281              :    REG_PARM_STACK_SPACE is nonzero if functions require stack space
    5282              :    for arguments passed in registers.  If nonzero, it will be the number
    5283              :    of bytes required.  */
    5284              : 
    5285              : bool
    5286      2160398 : emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
    5287              :                 unsigned int align, int partial, rtx reg, poly_int64 extra,
    5288              :                 rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
    5289              :                 rtx alignment_pad, bool sibcall_p)
    5290              : {
    5291      2160398 :   rtx xinner;
    5292      2160398 :   pad_direction stack_direction
    5293              :     = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
    5294              : 
    5295              :   /* Decide where to pad the argument: PAD_DOWNWARD for below,
    5296              :      PAD_UPWARD for above, or PAD_NONE for don't pad it.
    5297              :      Default is below for small data on big-endian machines; else above.  */
    5298      2160398 :   pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
    5299              : 
    5300              :   /* Invert direction if stack is post-decrement.
    5301              :      FIXME: why?  */
    5302      2160398 :   if (STACK_PUSH_CODE == POST_DEC)
    5303              :     if (where_pad != PAD_NONE)
    5304              :       where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
    5305              : 
    5306      2160398 :   xinner = x;
    5307              : 
    5308      2160398 :   int nregs = partial / UNITS_PER_WORD;
    5309      2160398 :   rtx *tmp_regs = NULL;
    5310      2160398 :   int overlapping = 0;
    5311              : 
    5312      2160398 :   if (mode == BLKmode
    5313              :       || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
    5314              :     {
    5315              :       /* Copy a block into the stack, entirely or partially.  */
    5316              : 
    5317       268233 :       rtx temp;
    5318       268233 :       int used;
    5319       268233 :       int offset;
    5320       268233 :       int skip;
    5321              : 
    5322       268233 :       offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
    5323       268233 :       used = partial - offset;
    5324              : 
    5325       268233 :       if (mode != BLKmode)
    5326              :         {
    5327              :           /* A value is to be stored in an insufficiently aligned
    5328              :              stack slot; copy via a suitably aligned slot if
    5329              :              necessary.  */
    5330              :           size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
    5331              :           if (!MEM_P (xinner))
    5332              :             {
    5333              :               temp = assign_temp (type, 1, 1);
    5334              :               emit_move_insn (temp, xinner);
    5335              :               xinner = temp;
    5336              :             }
    5337              :         }
    5338              : 
    5339       268233 :       gcc_assert (size);
    5340              : 
    5341              :       /* USED is now the # of bytes we need not copy to the stack
    5342              :          because registers will take care of them.  */
    5343              : 
    5344       268233 :       if (partial != 0)
    5345            0 :         xinner = adjust_address (xinner, BLKmode, used);
    5346              : 
    5347              :       /* If the partial register-part of the arg counts in its stack size,
    5348              :          skip the part of stack space corresponding to the registers.
    5349              :          Otherwise, start copying to the beginning of the stack space,
    5350              :          by setting SKIP to 0.  */
    5351       268233 :       skip = (reg_parm_stack_space == 0) ? 0 : used;
    5352              : 
    5353              : #ifdef PUSH_ROUNDING
    5354              :       /* NB: Let the backend known the number of bytes to push and
    5355              :          decide if push insns should be generated.  */
    5356       268233 :       unsigned int push_size;
    5357       268233 :       if (CONST_INT_P (size))
    5358       268233 :         push_size = INTVAL (size);
    5359              :       else
    5360              :         push_size = 0;
    5361              : 
    5362              :       /* Do it with several push insns if that doesn't take lots of insns
    5363              :          and if there is no difficulty with push insns that skip bytes
    5364              :          on the stack for alignment purposes.  */
    5365       268233 :       if (args_addr == 0
    5366       268179 :           && targetm.calls.push_argument (push_size)
    5367         3788 :           && CONST_INT_P (size)
    5368         3788 :           && skip == 0
    5369         3788 :           && MEM_ALIGN (xinner) >= align
    5370         2946 :           && can_move_by_pieces ((unsigned) INTVAL (size) - used, align)
    5371              :           /* Here we avoid the case of a structure whose weak alignment
    5372              :              forces many pushes of a small amount of data,
    5373              :              and such small pushes do rounding that causes trouble.  */
    5374         2946 :           && ((!targetm.slow_unaligned_access (word_mode, align))
    5375            0 :               || align >= BIGGEST_ALIGNMENT
    5376            0 :               || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
    5377              :                            align / BITS_PER_UNIT))
    5378       271179 :           && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
    5379              :         {
    5380              :           /* Push padding now if padding above and stack grows down,
    5381              :              or if padding below and stack grows up.
    5382              :              But if space already allocated, this has already been done.  */
    5383           45 :           if (maybe_ne (extra, 0)
    5384              :               && args_addr == 0
    5385            0 :               && where_pad != PAD_NONE
    5386           45 :               && where_pad != stack_direction)
    5387            0 :             anti_adjust_stack (gen_int_mode (extra, Pmode));
    5388              : 
    5389           45 :           move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
    5390              :                           RETURN_BEGIN);
    5391              :         }
    5392              :       else
    5393              : #endif /* PUSH_ROUNDING  */
    5394              :         {
    5395       268188 :           rtx target;
    5396              : 
    5397              :           /* Otherwise make space on the stack and copy the data
    5398              :              to the address of that space.  */
    5399              : 
    5400              :           /* Deduct words put into registers from the size we must copy.  */
    5401       268188 :           if (partial != 0)
    5402              :             {
    5403            0 :               if (CONST_INT_P (size))
    5404            0 :                 size = GEN_INT (INTVAL (size) - used);
    5405              :               else
    5406            0 :                 size = expand_binop (GET_MODE (size), sub_optab, size,
    5407            0 :                                      gen_int_mode (used, GET_MODE (size)),
    5408              :                                      NULL_RTX, 0, OPTAB_LIB_WIDEN);
    5409              :             }
    5410              : 
    5411              :           /* Get the address of the stack space.
    5412              :              In this case, we do not deal with EXTRA separately.
    5413              :              A single stack adjust will do.  */
    5414       268188 :           poly_int64 const_args_so_far;
    5415       268188 :           if (! args_addr)
    5416              :             {
    5417       268134 :               temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
    5418       268134 :               extra = 0;
    5419              :             }
    5420           54 :           else if (poly_int_rtx_p (args_so_far, &const_args_so_far))
    5421           72 :             temp = memory_address (BLKmode,
    5422              :                                    plus_constant (Pmode, args_addr,
    5423              :                                                   skip + const_args_so_far));
    5424              :           else
    5425            0 :             temp = memory_address (BLKmode,
    5426              :                                    plus_constant (Pmode,
    5427              :                                                   gen_rtx_PLUS (Pmode,
    5428              :                                                                 args_addr,
    5429              :                                                                 args_so_far),
    5430              :                                                   skip));
    5431              : 
    5432       268188 :           if (!ACCUMULATE_OUTGOING_ARGS)
    5433              :             {
    5434              :               /* If the source is referenced relative to the stack pointer,
    5435              :                  copy it to another register to stabilize it.  We do not need
    5436              :                  to do this if we know that we won't be changing sp.  */
    5437              : 
    5438       268188 :               if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
    5439       268188 :                   || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
    5440       268134 :                 temp = copy_to_reg (temp);
    5441              :             }
    5442              : 
    5443       268188 :           target = gen_rtx_MEM (BLKmode, temp);
    5444              : 
    5445              :           /* We do *not* set_mem_attributes here, because incoming arguments
    5446              :              may overlap with sibling call outgoing arguments and we cannot
    5447              :              allow reordering of reads from function arguments with stores
    5448              :              to outgoing arguments of sibling calls.  We do, however, want
    5449              :              to record the alignment of the stack slot.  */
    5450              :           /* ALIGN may well be better aligned than TYPE, e.g. due to
    5451              :              PARM_BOUNDARY.  Assume the caller isn't lying.  */
    5452       268188 :           set_mem_align (target, align);
    5453              : 
    5454              :           /* If part should go in registers and pushing to that part would
    5455              :              overwrite some of the values that need to go into regs, load the
    5456              :              overlapping values into temporary pseudos to be moved into the hard
    5457              :              regs at the end after the stack pushing has completed.
    5458              :              We cannot load them directly into the hard regs here because
    5459              :              they can be clobbered by the block move expansions.
    5460              :              See PR 65358.  */
    5461              : 
    5462       268188 :           if (partial > 0 && reg != 0 && mode == BLKmode
    5463            0 :               && GET_CODE (reg) != PARALLEL)
    5464              :             {
    5465            0 :               overlapping = memory_load_overlap (XEXP (x, 0), temp, partial);
    5466            0 :               if (overlapping > 0)
    5467              :                 {
    5468            0 :                   gcc_assert (overlapping % UNITS_PER_WORD == 0);
    5469            0 :                   overlapping /= UNITS_PER_WORD;
    5470              : 
    5471            0 :                   tmp_regs = XALLOCAVEC (rtx, overlapping);
    5472              : 
    5473            0 :                   for (int i = 0; i < overlapping; i++)
    5474            0 :                     tmp_regs[i] = gen_reg_rtx (word_mode);
    5475              : 
    5476            0 :                   for (int i = 0; i < overlapping; i++)
    5477            0 :                     emit_move_insn (tmp_regs[i],
    5478            0 :                                     operand_subword_force (target, i, mode));
    5479              :                 }
    5480            0 :               else if (overlapping == -1)
    5481              :                 overlapping = 0;
    5482              :               /* Could not determine whether there is overlap.
    5483              :                  Fail the sibcall.  */
    5484              :               else
    5485              :                 {
    5486            0 :                   overlapping = 0;
    5487            0 :                   if (sibcall_p)
    5488            0 :                     return false;
    5489              :                 }
    5490              :             }
    5491              : 
    5492              :           /* If source is a constant VAR_DECL with a simple constructor,
    5493              :              store the constructor to the stack instead of moving it.  */
    5494       268188 :           const_tree decl;
    5495       268188 :           HOST_WIDE_INT sz;
    5496       268188 :           if (partial == 0
    5497       268188 :               && MEM_P (xinner)
    5498       268188 :               && SYMBOL_REF_P (XEXP (xinner, 0))
    5499        81882 :               && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
    5500        81882 :               && VAR_P (decl)
    5501        81882 :               && TREE_READONLY (decl)
    5502         4505 :               && !TREE_SIDE_EFFECTS (decl)
    5503         4505 :               && immediate_const_ctor_p (DECL_INITIAL (decl), 2)
    5504            9 :               && (sz = int_expr_size (DECL_INITIAL (decl))) > 0
    5505            9 :               && CONST_INT_P (size)
    5506       268197 :               && INTVAL (size) == sz)
    5507            3 :             store_constructor (DECL_INITIAL (decl), target, 0, sz, false);
    5508              :           else
    5509       268185 :             emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
    5510              :         }
    5511              :     }
    5512      1892165 :   else if (partial > 0)
    5513              :     {
    5514              :       /* Scalar partly in registers.  This case is only supported
    5515              :          for fixed-wdth modes.  */
    5516            0 :       int num_words = GET_MODE_SIZE (mode).to_constant ();
    5517            0 :       num_words /= UNITS_PER_WORD;
    5518            0 :       int i;
    5519            0 :       int not_stack;
    5520              :       /* # bytes of start of argument
    5521              :          that we must make space for but need not store.  */
    5522            0 :       int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
    5523            0 :       int args_offset = INTVAL (args_so_far);
    5524            0 :       int skip;
    5525              : 
    5526              :       /* Push padding now if padding above and stack grows down,
    5527              :          or if padding below and stack grows up.
    5528              :          But if space already allocated, this has already been done.  */
    5529            0 :       if (maybe_ne (extra, 0)
    5530            0 :           && args_addr == 0
    5531            0 :           && where_pad != PAD_NONE
    5532            0 :           && where_pad != stack_direction)
    5533            0 :         anti_adjust_stack (gen_int_mode (extra, Pmode));
    5534              : 
    5535              :       /* If we make space by pushing it, we might as well push
    5536              :          the real data.  Otherwise, we can leave OFFSET nonzero
    5537              :          and leave the space uninitialized.  */
    5538            0 :       if (args_addr == 0)
    5539            0 :         offset = 0;
    5540              : 
    5541              :       /* Now NOT_STACK gets the number of words that we don't need to
    5542              :          allocate on the stack.  Convert OFFSET to words too.  */
    5543            0 :       not_stack = (partial - offset) / UNITS_PER_WORD;
    5544            0 :       offset /= UNITS_PER_WORD;
    5545              : 
    5546              :       /* If the partial register-part of the arg counts in its stack size,
    5547              :          skip the part of stack space corresponding to the registers.
    5548              :          Otherwise, start copying to the beginning of the stack space,
    5549              :          by setting SKIP to 0.  */
    5550            0 :       skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
    5551              : 
    5552            0 :       if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
    5553            0 :         x = validize_mem (force_const_mem (mode, x));
    5554              : 
    5555              :       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
    5556              :          SUBREGs of such registers are not allowed.  */
    5557            0 :       if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
    5558            0 :            && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
    5559            0 :         x = copy_to_reg (x);
    5560              : 
    5561              :       /* Loop over all the words allocated on the stack for this arg.  */
    5562              :       /* We can do it by words, because any scalar bigger than a word
    5563              :          has a size a multiple of a word.  */
    5564            0 :       tree word_mode_type = lang_hooks.types.type_for_mode (word_mode, 1);
    5565            0 :       for (i = num_words - 1; i >= not_stack; i--)
    5566            0 :         if (i >= not_stack + offset)
    5567            0 :           if (!emit_push_insn (operand_subword_force (x, i, mode),
    5568              :                           word_mode, word_mode_type, NULL_RTX, align, 0,
    5569              :                           NULL_RTX, 0, args_addr,
    5570            0 :                           GEN_INT (args_offset + ((i - not_stack + skip)
    5571              :                                                   * UNITS_PER_WORD)),
    5572              :                           reg_parm_stack_space, alignment_pad, sibcall_p))
    5573            0 :             return false;
    5574              :     }
    5575              :   else
    5576              :     {
    5577      1892165 :       rtx addr;
    5578      1892165 :       rtx dest;
    5579              : 
    5580              :       /* Push padding now if padding above and stack grows down,
    5581              :          or if padding below and stack grows up.
    5582              :          But if space already allocated, this has already been done.  */
    5583      1892165 :       if (maybe_ne (extra, 0)
    5584            0 :           && args_addr == 0
    5585            0 :           && where_pad != PAD_NONE
    5586      1892165 :           && where_pad != stack_direction)
    5587            0 :         anti_adjust_stack (gen_int_mode (extra, Pmode));
    5588              : 
    5589              : #ifdef PUSH_ROUNDING
    5590      1892165 :       if (args_addr == 0 && targetm.calls.push_argument (0))
    5591      1836777 :         emit_single_push_insn (mode, x, type);
    5592              :       else
    5593              : #endif
    5594              :         {
    5595        63656 :           addr = simplify_gen_binary (PLUS, Pmode, args_addr, args_so_far);
    5596        55388 :           dest = gen_rtx_MEM (mode, memory_address (mode, addr));
    5597              : 
    5598              :           /* We do *not* set_mem_attributes here, because incoming arguments
    5599              :              may overlap with sibling call outgoing arguments and we cannot
    5600              :              allow reordering of reads from function arguments with stores
    5601              :              to outgoing arguments of sibling calls.  We do, however, want
    5602              :              to record the alignment of the stack slot.  */
    5603              :           /* ALIGN may well be better aligned than TYPE, e.g. due to
    5604              :              PARM_BOUNDARY.  Assume the caller isn't lying.  */
    5605        55388 :           set_mem_align (dest, align);
    5606              : 
    5607        55388 :           emit_move_insn (dest, x);
    5608              :         }
    5609              :     }
    5610              : 
    5611              :   /* Move the partial arguments into the registers and any overlapping
    5612              :      values that we moved into the pseudos in tmp_regs.  */
    5613      2160398 :   if (partial > 0 && reg != 0)
    5614              :     {
    5615              :       /* Handle calls that pass values in multiple non-contiguous locations.
    5616              :          The Irix 6 ABI has examples of this.  */
    5617            0 :       if (GET_CODE (reg) == PARALLEL)
    5618            0 :         emit_group_load (reg, x, type, -1);
    5619              :       else
    5620              :         {
    5621            0 :           gcc_assert (partial % UNITS_PER_WORD == 0);
    5622            0 :           move_block_to_reg (REGNO (reg), x, nregs - overlapping, mode);
    5623              : 
    5624            0 :           for (int i = 0; i < overlapping; i++)
    5625            0 :             emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg)
    5626            0 :                                                     + nregs - overlapping + i),
    5627            0 :                             tmp_regs[i]);
    5628              : 
    5629              :         }
    5630              :     }
    5631              : 
    5632      2160398 :   if (maybe_ne (extra, 0) && args_addr == 0 && where_pad == stack_direction)
    5633            0 :     anti_adjust_stack (gen_int_mode (extra, Pmode));
    5634              : 
    5635      2160398 :   if (alignment_pad && args_addr == 0)
    5636      2104956 :     anti_adjust_stack (alignment_pad);
    5637              : 
    5638              :   return true;
    5639              : }
    5640              : 
    5641              : /* Return X if X can be used as a subtarget in a sequence of arithmetic
    5642              :    operations.  */
    5643              : 
    5644              : static rtx
    5645    198936763 : get_subtarget (rtx x)
    5646              : {
    5647    198936763 :   return (optimize
    5648     51694337 :           || x == 0
    5649              :            /* Only registers can be subtargets.  */
    5650     17310261 :            || !REG_P (x)
    5651              :            /* Don't use hard regs to avoid extending their life.  */
    5652     11748630 :            || REGNO (x) < FIRST_PSEUDO_REGISTER
    5653    198936763 :           ? 0 : x);
    5654              : }
    5655              : 
    5656              : /* A subroutine of expand_assignment.  Optimize FIELD op= VAL, where
    5657              :    FIELD is a bitfield.  Returns true if the optimization was successful,
    5658              :    and there's nothing else to do.  */
    5659              : 
    5660              : static bool
    5661      4652864 : optimize_bitfield_assignment_op (poly_uint64 pbitsize,
    5662              :                                  poly_uint64 pbitpos,
    5663              :                                  poly_uint64 pbitregion_start,
    5664              :                                  poly_uint64 pbitregion_end,
    5665              :                                  machine_mode mode1, rtx str_rtx,
    5666              :                                  tree to, tree src, bool reverse)
    5667              : {
    5668              :   /* str_mode is not guaranteed to be a scalar type.  */
    5669      4652864 :   machine_mode str_mode = GET_MODE (str_rtx);
    5670      4652864 :   unsigned int str_bitsize;
    5671      4652864 :   tree op0, op1;
    5672      4652864 :   rtx value, result;
    5673      4652864 :   optab binop;
    5674      4652864 :   gimple *srcstmt;
    5675      4652864 :   enum tree_code code;
    5676              : 
    5677      4652864 :   unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
    5678      4652864 :   if (mode1 != VOIDmode
    5679        67687 :       || !pbitsize.is_constant (&bitsize)
    5680        67687 :       || !pbitpos.is_constant (&bitpos)
    5681        67687 :       || !pbitregion_start.is_constant (&bitregion_start)
    5682        67687 :       || !pbitregion_end.is_constant (&bitregion_end)
    5683        68261 :       || bitsize >= BITS_PER_WORD
    5684        67418 :       || !GET_MODE_BITSIZE (str_mode).is_constant (&str_bitsize)
    5685        67992 :       || str_bitsize > BITS_PER_WORD
    5686        62020 :       || TREE_SIDE_EFFECTS (to)
    5687      4714755 :       || TREE_THIS_VOLATILE (to))
    5688              :     return false;
    5689              : 
    5690        61891 :   STRIP_NOPS (src);
    5691        61891 :   if (TREE_CODE (src) != SSA_NAME)
    5692              :     return false;
    5693        20831 :   if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
    5694              :     return false;
    5695              : 
    5696        19269 :   srcstmt = get_gimple_for_ssa_name (src);
    5697        19269 :   if (!srcstmt
    5698         4515 :       || !is_gimple_assign (srcstmt)
    5699        23784 :       || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
    5700              :     return false;
    5701              : 
    5702          808 :   code = gimple_assign_rhs_code (srcstmt);
    5703              : 
    5704          808 :   op0 = gimple_assign_rhs1 (srcstmt);
    5705              : 
    5706              :   /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
    5707              :      to find its initialization.  Hopefully the initialization will
    5708              :      be from a bitfield load.  */
    5709          808 :   if (TREE_CODE (op0) == SSA_NAME)
    5710              :     {
    5711          808 :       gimple *op0stmt = get_gimple_for_ssa_name (op0);
    5712              : 
    5713              :       /* We want to eventually have OP0 be the same as TO, which
    5714              :          should be a bitfield.  */
    5715          808 :       if (!op0stmt
    5716          755 :           || !is_gimple_assign (op0stmt)
    5717         1563 :           || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
    5718              :         return false;
    5719          542 :       op0 = gimple_assign_rhs1 (op0stmt);
    5720              :     }
    5721              : 
    5722          542 :   op1 = gimple_assign_rhs2 (srcstmt);
    5723              : 
    5724          542 :   if (!operand_equal_p (to, op0, 0))
    5725              :     return false;
    5726              : 
    5727          462 :   if (MEM_P (str_rtx))
    5728              :     {
    5729          421 :       unsigned HOST_WIDE_INT offset1;
    5730              : 
    5731          421 :       if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
    5732           80 :         str_bitsize = BITS_PER_WORD;
    5733              : 
    5734          421 :       scalar_int_mode best_mode;
    5735          421 :       if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
    5736          421 :                           MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
    5737            0 :         return false;
    5738          421 :       str_mode = best_mode;
    5739          421 :       str_bitsize = GET_MODE_BITSIZE (best_mode);
    5740              : 
    5741          421 :       offset1 = bitpos;
    5742          421 :       bitpos %= str_bitsize;
    5743          421 :       offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
    5744          421 :       str_rtx = adjust_address (str_rtx, str_mode, offset1);
    5745              :     }
    5746           41 :   else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
    5747              :     return false;
    5748              : 
    5749              :   /* If the bit field covers the whole REG/MEM, store_field
    5750              :      will likely generate better code.  */
    5751          462 :   if (bitsize >= str_bitsize)
    5752              :     return false;
    5753              : 
    5754              :   /* We can't handle fields split across multiple entities.  */
    5755          462 :   if (bitpos + bitsize > str_bitsize)
    5756              :     return false;
    5757              : 
    5758          462 :   if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
    5759            0 :     bitpos = str_bitsize - bitpos - bitsize;
    5760              : 
    5761          462 :   switch (code)
    5762              :     {
    5763          141 :     case PLUS_EXPR:
    5764          141 :     case MINUS_EXPR:
    5765              :       /* For now, just optimize the case of the topmost bitfield
    5766              :          where we don't need to do any masking and also
    5767              :          1 bit bitfields where xor can be used.
    5768              :          We might win by one instruction for the other bitfields
    5769              :          too if insv/extv instructions aren't used, so that
    5770              :          can be added later.  */
    5771          141 :       if ((reverse || bitpos + bitsize != str_bitsize)
    5772           97 :           && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
    5773              :         break;
    5774              : 
    5775           70 :       value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
    5776           70 :       value = convert_modes (str_mode,
    5777           70 :                              TYPE_MODE (TREE_TYPE (op1)), value,
    5778           70 :                              TYPE_UNSIGNED (TREE_TYPE (op1)));
    5779              : 
    5780              :       /* We may be accessing data outside the field, which means
    5781              :          we can alias adjacent data.  */
    5782           70 :       if (MEM_P (str_rtx))
    5783              :         {
    5784           70 :           str_rtx = shallow_copy_rtx (str_rtx);
    5785           70 :           set_mem_alias_set (str_rtx, 0);
    5786           70 :           set_mem_expr (str_rtx, 0);
    5787              :         }
    5788              : 
    5789           70 :       if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
    5790              :         {
    5791           26 :           value = expand_and (str_mode, value, const1_rtx, NULL);
    5792           26 :           binop = xor_optab;
    5793              :         }
    5794              :       else
    5795           44 :         binop = code == PLUS_EXPR ? add_optab : sub_optab;
    5796              : 
    5797           70 :       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
    5798           70 :       if (reverse)
    5799            0 :         value = flip_storage_order (str_mode, value);
    5800           70 :       result = expand_binop (str_mode, binop, str_rtx,
    5801              :                              value, str_rtx, 1, OPTAB_WIDEN);
    5802           70 :       if (result != str_rtx)
    5803            0 :         emit_move_insn (str_rtx, result);
    5804              :       return true;
    5805              : 
    5806          253 :     case BIT_IOR_EXPR:
    5807          253 :     case BIT_XOR_EXPR:
    5808          253 :       if (TREE_CODE (op1) != INTEGER_CST)
    5809              :         break;
    5810           97 :       value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
    5811           97 :       value = convert_modes (str_mode,
    5812           97 :                              TYPE_MODE (TREE_TYPE (op1)), value,
    5813           97 :                              TYPE_UNSIGNED (TREE_TYPE (op1)));
    5814              : 
    5815              :       /* We may be accessing data outside the field, which means
    5816              :          we can alias adjacent data.  */
    5817           97 :       if (MEM_P (str_rtx))
    5818              :         {
    5819           61 :           str_rtx = shallow_copy_rtx (str_rtx);
    5820           61 :           set_mem_alias_set (str_rtx, 0);
    5821           61 :           set_mem_expr (str_rtx, 0);
    5822              :         }
    5823              : 
    5824           97 :       binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
    5825           97 :       if (bitpos + bitsize != str_bitsize)
    5826              :         {
    5827           55 :           rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
    5828              :                                    str_mode);
    5829           55 :           value = expand_and (str_mode, value, mask, NULL_RTX);
    5830              :         }
    5831           97 :       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
    5832           97 :       if (reverse)
    5833            0 :         value = flip_storage_order (str_mode, value);
    5834           97 :       result = expand_binop (str_mode, binop, str_rtx,
    5835              :                              value, str_rtx, 1, OPTAB_WIDEN);
    5836           97 :       if (result != str_rtx)
    5837            0 :         emit_move_insn (str_rtx, result);
    5838              :       return true;
    5839              : 
    5840              :     default:
    5841              :       break;
    5842              :     }
    5843              : 
    5844              :   return false;
    5845              : }
    5846              : 
    5847              : /* In the C++ memory model, consecutive bit fields in a structure are
    5848              :    considered one memory location.
    5849              : 
    5850              :    Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
    5851              :    returns the bit range of consecutive bits in which this COMPONENT_REF
    5852              :    belongs.  The values are returned in *BITSTART and *BITEND.  *BITPOS
    5853              :    and *OFFSET may be adjusted in the process.
    5854              : 
    5855              :    If the access does not need to be restricted, 0 is returned in both
    5856              :    *BITSTART and *BITEND.  */
    5857              : 
    5858              : void
    5859      2914873 : get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
    5860              :                poly_int64 *bitpos, tree *offset)
    5861              : {
    5862      2914873 :   poly_int64 bitoffset;
    5863      2914873 :   tree field, repr;
    5864              : 
    5865      2914873 :   gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
    5866              : 
    5867      2914873 :   field = TREE_OPERAND (exp, 1);
    5868      2914873 :   repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
    5869              :   /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
    5870              :      need to limit the range we can access.  */
    5871      2914873 :   if (!repr)
    5872              :     {
    5873           65 :       *bitstart = *bitend = 0;
    5874           65 :       return;
    5875              :     }
    5876              : 
    5877              :   /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
    5878              :      part of a larger bit field, then the representative does not serve any
    5879              :      useful purpose.  This can occur in Ada.  */
    5880      2914808 :   if (handled_component_p (TREE_OPERAND (exp, 0)))
    5881              :     {
    5882      2394294 :       machine_mode rmode;
    5883      2394294 :       poly_int64 rbitsize, rbitpos;
    5884      2394294 :       tree roffset;
    5885      2394294 :       int unsignedp, reversep, volatilep = 0;
    5886      2394294 :       get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
    5887              :                            &roffset, &rmode, &unsignedp, &reversep,
    5888              :                            &volatilep);
    5889      4788588 :       if (!multiple_p (rbitpos, BITS_PER_UNIT))
    5890              :         {
    5891            0 :           *bitstart = *bitend = 0;
    5892            0 :           return;
    5893              :         }
    5894              :     }
    5895              : 
    5896              :   /* Compute the adjustment to bitpos from the offset of the field
    5897              :      relative to the representative.  DECL_FIELD_OFFSET of field and
    5898              :      repr are the same by construction if they are not constants,
    5899              :      see finish_bitfield_layout.  */
    5900      2914808 :   poly_uint64 field_offset, repr_offset;
    5901      2914808 :   if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
    5902      5829611 :       && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
    5903      2914803 :     bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
    5904              :   else
    5905              :     bitoffset = 0;
    5906      2914808 :   bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
    5907      2914808 :                 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
    5908              : 
    5909              :   /* If the adjustment is larger than bitpos, we would have a negative bit
    5910              :      position for the lower bound and this may wreak havoc later.  Adjust
    5911              :      offset and bitpos to make the lower bound non-negative in that case.  */
    5912      2914808 :   if (maybe_gt (bitoffset, *bitpos))
    5913              :     {
    5914            9 :       poly_int64 adjust_bits = upper_bound (bitoffset, *bitpos) - *bitpos;
    5915            9 :       poly_int64 adjust_bytes = exact_div (adjust_bits, BITS_PER_UNIT);
    5916              : 
    5917            9 :       *bitpos += adjust_bits;
    5918            9 :       if (*offset == NULL_TREE)
    5919            5 :         *offset = size_int (-adjust_bytes);
    5920              :       else
    5921            4 :         *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
    5922            9 :       *bitstart = 0;
    5923              :     }
    5924              :   else
    5925      2914799 :     *bitstart = *bitpos - bitoffset;
    5926              : 
    5927      2914808 :   *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
    5928              : }
    5929              : 
    5930              : /* Returns true if BASE is a DECL that does not reside in memory and
    5931              :    has non-BLKmode.  DECL_RTL must not be a MEM; if
    5932              :    DECL_RTL was not set yet, return false.  */
    5933              : 
    5934              : bool
    5935      5343605 : non_mem_decl_p (tree base)
    5936              : {
    5937      5343605 :   if (!DECL_P (base)
    5938      5343238 :       || TREE_ADDRESSABLE (base)
    5939      7756966 :       || DECL_MODE (base) == BLKmode)
    5940              :     return false;
    5941              : 
    5942      1565057 :   if (!DECL_RTL_SET_P (base))
    5943              :     return false;
    5944              : 
    5945      1447125 :   return (!MEM_P (DECL_RTL (base)));
    5946              : }
    5947              : 
    5948              : /* Returns true if REF refers to an object that does not
    5949              :    reside in memory and has non-BLKmode.  */
    5950              : 
    5951              : bool
    5952     11684043 : mem_ref_refers_to_non_mem_p (tree ref)
    5953              : {
    5954     11684043 :   tree base;
    5955              : 
    5956     11684043 :   if (TREE_CODE (ref) == MEM_REF
    5957     11684043 :       || TREE_CODE (ref) == TARGET_MEM_REF)
    5958              :     {
    5959     10187123 :       tree addr = TREE_OPERAND (ref, 0);
    5960              : 
    5961     10187123 :       if (TREE_CODE (addr) != ADDR_EXPR)
    5962              :         return false;
    5963              : 
    5964      3829610 :       base = TREE_OPERAND (addr, 0);
    5965              :     }
    5966              :   else
    5967              :     base = ref;
    5968              : 
    5969      5326530 :   return non_mem_decl_p (base);
    5970              : }
    5971              : 
    5972              : /* Helper function of expand_assignment.  Check if storing field of
    5973              :    size BITSIZE at position BITPOS overlaps with the most significant
    5974              :    bit of TO_RTX, known to be SUBREG_PROMOTED_VAR_P.
    5975              :    Updating this field requires an explicit extension.  */
    5976              : static bool
    5977            0 : store_field_updates_msb_p (poly_int64 bitpos, poly_int64 bitsize, rtx to_rtx)
    5978              : {
    5979            0 :   poly_int64 to_size = GET_MODE_SIZE (GET_MODE (to_rtx));
    5980            0 :   poly_int64 bitnum = BYTES_BIG_ENDIAN ? to_size - bitsize - bitpos : bitpos;
    5981            0 :   return maybe_eq (bitnum + bitsize, to_size);
    5982              : }
    5983              : 
    5984              : /* Expand an assignment that stores the value of FROM into TO.  If NONTEMPORAL
    5985              :    is true, try generating a nontemporal store.  */
    5986              : 
    5987              : void
    5988     18203290 : expand_assignment (tree to, tree from, bool nontemporal)
    5989              : {
    5990     18203290 :   rtx to_rtx = 0;
    5991     18203290 :   rtx result;
    5992     18203290 :   machine_mode mode;
    5993     18203290 :   unsigned int align;
    5994     18203290 :   enum insn_code icode;
    5995              : 
    5996              :   /* Don't crash if the lhs of the assignment was erroneous.  */
    5997     18203290 :   if (TREE_CODE (to) == ERROR_MARK)
    5998              :     {
    5999            0 :       expand_normal (from);
    6000            0 :       return;
    6001              :     }
    6002              : 
    6003              :   /* Optimize away no-op moves without side-effects.  */
    6004     18203290 :   if (operand_equal_p (to, from, 0))
    6005              :     return;
    6006              : 
    6007              :   /* Handle misaligned stores.  */
    6008     18203136 :   mode = TYPE_MODE (TREE_TYPE (to));
    6009     18203136 :   if ((TREE_CODE (to) == MEM_REF
    6010     18203136 :        || TREE_CODE (to) == TARGET_MEM_REF
    6011     16046491 :        || DECL_P (to))
    6012      3987409 :       && mode != BLKmode
    6013      3524764 :       && !mem_ref_refers_to_non_mem_p (to)
    6014      6313744 :       && ((align = get_object_alignment (to))
    6015      3156872 :           < GET_MODE_ALIGNMENT (mode))
    6016     18630576 :       && (((icode = optab_handler (movmisalign_optab, mode))
    6017              :            != CODE_FOR_nothing)
    6018        97890 :           || targetm.slow_unaligned_access (mode, align)))
    6019              :     {
    6020       329550 :       rtx reg, mem;
    6021              : 
    6022       329550 :       reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
    6023              :       /* Handle PARALLEL.  */
    6024       329550 :       reg = maybe_emit_group_store (reg, TREE_TYPE (from));
    6025       329550 :       reg = force_not_mem (reg);
    6026       329550 :       mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6027       329550 :       if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
    6028            0 :         reg = flip_storage_order (mode, reg);
    6029              : 
    6030       329550 :       if (icode != CODE_FOR_nothing)
    6031              :         {
    6032       329550 :           class expand_operand ops[2];
    6033              : 
    6034       329550 :           create_fixed_operand (&ops[0], mem);
    6035       329550 :           create_input_operand (&ops[1], reg, mode);
    6036              :           /* The movmisalign<mode> pattern cannot fail, else the assignment
    6037              :              would silently be omitted.  */
    6038       329550 :           expand_insn (icode, 2, ops);
    6039              :         }
    6040              :       else
    6041            0 :         store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
    6042              :                          false, false);
    6043       329550 :       return;
    6044              :     }
    6045              : 
    6046              :   /* Assignment of a structure component needs special treatment
    6047              :      if the structure component's rtx is not simply a MEM.
    6048              :      Assignment of an array element at a constant index, and assignment of
    6049              :      an array element in an unaligned packed structure field, has the same
    6050              :      problem.  Same for (partially) storing into a non-memory object.  */
    6051     17873586 :   if (handled_component_p (to)
    6052     13446409 :       || (TREE_CODE (to) == MEM_REF
    6053      1592650 :           && (REF_REVERSE_STORAGE_ORDER (to)
    6054      1592570 :               || mem_ref_refers_to_non_mem_p (to)))
    6055     13340275 :       || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
    6056              :     {
    6057      4653024 :       machine_mode mode1;
    6058      4653024 :       poly_int64 bitsize, bitpos;
    6059      4653024 :       poly_uint64 bitregion_start = 0;
    6060      4653024 :       poly_uint64 bitregion_end = 0;
    6061      4653024 :       tree offset;
    6062      4653024 :       int unsignedp, reversep, volatilep = 0;
    6063      4653024 :       tree tem;
    6064              : 
    6065      4653024 :       push_temp_slots ();
    6066      4653024 :       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
    6067              :                                  &unsignedp, &reversep, &volatilep);
    6068              : 
    6069              :       /* Make sure bitpos is not negative, it can wreak havoc later.  */
    6070      4653024 :       if (maybe_lt (bitpos, 0))
    6071              :         {
    6072          224 :           gcc_assert (offset == NULL_TREE);
    6073          224 :           offset = size_int (bits_to_bytes_round_down (bitpos));
    6074          224 :           bitpos = num_trailing_bits (bitpos);
    6075              :         }
    6076              : 
    6077      4653024 :       if (TREE_CODE (to) == COMPONENT_REF
    6078      4653024 :           && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
    6079        86240 :         get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
    6080              :       /* The C++ memory model naturally applies to byte-aligned fields.
    6081              :          However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
    6082              :          BITSIZE are not byte-aligned, there is no need to limit the range
    6083              :          we can access.  This can occur with packed structures in Ada.  */
    6084      4566784 :       else if (maybe_gt (bitsize, 0)
    6085      4566769 :                && multiple_p (bitsize, BITS_PER_UNIT)
    6086      9133294 :                && multiple_p (bitpos, BITS_PER_UNIT))
    6087              :         {
    6088      4566510 :           bitregion_start = bitpos;
    6089      4566510 :           bitregion_end = bitpos + bitsize - 1;
    6090              :         }
    6091              : 
    6092      4653024 :       to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6093              : 
    6094              :       /* If the field has a mode, we want to access it in the
    6095              :          field's mode, not the computed mode.
    6096              :          If a MEM has VOIDmode (external with incomplete type),
    6097              :          use BLKmode for it instead.  */
    6098      4653024 :       if (MEM_P (to_rtx))
    6099              :         {
    6100      3988195 :           if (mode1 != VOIDmode)
    6101      3921249 :             to_rtx = adjust_address (to_rtx, mode1, 0);
    6102        66946 :           else if (GET_MODE (to_rtx) == VOIDmode)
    6103            0 :             to_rtx = adjust_address (to_rtx, BLKmode, 0);
    6104              :         }
    6105              : 
    6106      4653024 :       rtx stemp = NULL_RTX, old_to_rtx = NULL_RTX;
    6107      4653024 :       if (offset != 0)
    6108              :         {
    6109       176508 :           machine_mode address_mode;
    6110       176508 :           rtx offset_rtx;
    6111              : 
    6112       176508 :           if (!MEM_P (to_rtx))
    6113              :             {
    6114              :               /* We can get constant negative offsets into arrays with broken
    6115              :                  user code.  Translate this to a trap instead of ICEing.  */
    6116            4 :               if (TREE_CODE (offset) == INTEGER_CST)
    6117              :                 {
    6118            1 :                   expand_builtin_trap ();
    6119            1 :                   to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
    6120              :                 }
    6121              :               /* Else spill for variable offset to the destination.  We expect
    6122              :                  to run into this only for hard registers.  */
    6123              :               else
    6124              :                 {
    6125            3 :                   gcc_assert (VAR_P (tem) && DECL_HARD_REGISTER (tem));
    6126            3 :                   stemp = assign_stack_temp (GET_MODE (to_rtx),
    6127            6 :                                              GET_MODE_SIZE (GET_MODE (to_rtx)));
    6128            3 :                   emit_move_insn (stemp, to_rtx);
    6129            3 :                   old_to_rtx = to_rtx;
    6130            3 :                   to_rtx = stemp;
    6131              :                 }
    6132              :             }
    6133              : 
    6134       176508 :           offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
    6135       176508 :           address_mode = get_address_mode (to_rtx);
    6136       176508 :           if (GET_MODE (offset_rtx) != address_mode)
    6137              :             {
    6138              :                 /* We cannot be sure that the RTL in offset_rtx is valid outside
    6139              :                    of a memory address context, so force it into a register
    6140              :                    before attempting to convert it to the desired mode.  */
    6141          248 :               offset_rtx = force_operand (offset_rtx, NULL_RTX);
    6142          248 :               offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
    6143              :             }
    6144              : 
    6145              :           /* If we have an expression in OFFSET_RTX and a non-zero
    6146              :              byte offset in BITPOS, adding the byte offset before the
    6147              :              OFFSET_RTX results in better intermediate code, which makes
    6148              :              later rtl optimization passes perform better.
    6149              : 
    6150              :              We prefer intermediate code like this:
    6151              : 
    6152              :              r124:DI=r123:DI+0x18
    6153              :              [r124:DI]=r121:DI
    6154              : 
    6155              :              ... instead of ...
    6156              : 
    6157              :              r124:DI=r123:DI+0x10
    6158              :              [r124:DI+0x8]=r121:DI
    6159              : 
    6160              :              This is only done for aligned data values, as these can
    6161              :              be expected to result in single move instructions.  */
    6162       176508 :           poly_int64 bytepos;
    6163       176508 :           if (mode1 != VOIDmode
    6164       176400 :               && maybe_ne (bitpos, 0)
    6165        47858 :               && maybe_gt (bitsize, 0)
    6166       224366 :               && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
    6167       224242 :               && multiple_p (bitpos, bitsize)
    6168        95468 :               && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
    6169       224242 :               && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
    6170              :             {
    6171        47487 :               to_rtx = adjust_address (to_rtx, mode1, bytepos);
    6172        47487 :               bitregion_start = 0;
    6173        47487 :               if (known_ge (bitregion_end, poly_uint64 (bitpos)))
    6174        47487 :                 bitregion_end -= bitpos;
    6175        47487 :               bitpos = 0;
    6176              :             }
    6177              : 
    6178       176508 :           to_rtx = offset_address (to_rtx, offset_rtx,
    6179              :                                    highest_pow2_factor_for_target (to,
    6180              :                                                                    offset));
    6181              :         }
    6182              : 
    6183              :       /* No action is needed if the target is not a memory and the field
    6184              :          lies completely outside that target.  This can occur if the source
    6185              :          code contains an out-of-bounds access to a small array.  */
    6186      4653024 :       if (!MEM_P (to_rtx)
    6187       664825 :           && GET_MODE (to_rtx) != BLKmode
    6188      5317849 :           && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
    6189              :         {
    6190            3 :           expand_normal (from);
    6191            3 :           result = NULL;
    6192              :         }
    6193              :       /* Handle expand_expr of a complex value returning a CONCAT.  */
    6194      4653021 :       else if (GET_CODE (to_rtx) == CONCAT)
    6195              :         {
    6196          151 :           machine_mode to_mode = GET_MODE (to_rtx);
    6197          151 :           gcc_checking_assert (COMPLEX_MODE_P (to_mode));
    6198          302 :           poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode);
    6199          151 :           unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
    6200          151 :           if (TYPE_MODE (TREE_TYPE (from)) == to_mode
    6201            0 :               && known_eq (bitpos, 0)
    6202          151 :               && known_eq (bitsize, mode_bitsize))
    6203            0 :             result = store_expr (from, to_rtx, false, nontemporal, reversep);
    6204          151 :           else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
    6205          102 :                    && known_eq (bitsize, inner_bitsize)
    6206          253 :                    && (known_eq (bitpos, 0)
    6207           31 :                        || known_eq (bitpos, inner_bitsize)))
    6208          102 :             result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
    6209              :                                  false, nontemporal, reversep);
    6210           49 :           else if (known_le (bitpos + bitsize, inner_bitsize))
    6211            5 :             result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
    6212              :                                   bitregion_start, bitregion_end,
    6213              :                                   mode1, from, get_alias_set (to),
    6214              :                                   nontemporal, reversep);
    6215           44 :           else if (known_ge (bitpos, inner_bitsize))
    6216            3 :             result = store_field (XEXP (to_rtx, 1), bitsize,
    6217              :                                   bitpos - inner_bitsize,
    6218              :                                   bitregion_start, bitregion_end,
    6219              :                                   mode1, from, get_alias_set (to),
    6220              :                                   nontemporal, reversep);
    6221           41 :           else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
    6222              :             {
    6223           34 :               result = expand_normal (from);
    6224           34 :               if (GET_CODE (result) == CONCAT)
    6225              :                 {
    6226            0 :                   to_mode = GET_MODE_INNER (to_mode);
    6227            0 :                   machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
    6228            0 :                   rtx from_real
    6229            0 :                     = force_subreg (to_mode, XEXP (result, 0), from_mode, 0);
    6230            0 :                   rtx from_imag
    6231            0 :                     = force_subreg (to_mode, XEXP (result, 1), from_mode, 0);
    6232            0 :                   if (!from_real || !from_imag)
    6233            0 :                     goto concat_store_slow;
    6234            0 :                   emit_move_insn (XEXP (to_rtx, 0), from_real);
    6235            0 :                   emit_move_insn (XEXP (to_rtx, 1), from_imag);
    6236              :                 }
    6237              :               else
    6238              :                 {
    6239           34 :                   machine_mode from_mode
    6240           34 :                     = GET_MODE (result) == VOIDmode
    6241           34 :                       ? TYPE_MODE (TREE_TYPE (from))
    6242           34 :                       : GET_MODE (result);
    6243           34 :                   rtx from_rtx;
    6244           34 :                   if (MEM_P (result))
    6245            1 :                     from_rtx = change_address (result, to_mode, NULL_RTX);
    6246              :                   else
    6247           33 :                     from_rtx = force_subreg (to_mode, result, from_mode, 0);
    6248           34 :                   if (from_rtx)
    6249              :                     {
    6250           34 :                       emit_move_insn (XEXP (to_rtx, 0),
    6251              :                                       read_complex_part (from_rtx, false));
    6252           34 :                       emit_move_insn (XEXP (to_rtx, 1),
    6253              :                                       read_complex_part (from_rtx, true));
    6254              :                     }
    6255              :                   else
    6256              :                     {
    6257            0 :                       to_mode = GET_MODE_INNER (to_mode);
    6258            0 :                       rtx from_real
    6259            0 :                         = force_subreg (to_mode, result, from_mode, 0);
    6260            0 :                       rtx from_imag
    6261            0 :                         = force_subreg (to_mode, result, from_mode,
    6262            0 :                                         GET_MODE_SIZE (to_mode));
    6263            0 :                       if (!from_real || !from_imag)
    6264            0 :                         goto concat_store_slow;
    6265            0 :                       emit_move_insn (XEXP (to_rtx, 0), from_real);
    6266            0 :                       emit_move_insn (XEXP (to_rtx, 1), from_imag);
    6267              :                     }
    6268              :                 }
    6269              :             }
    6270              :           else
    6271              :             {
    6272            7 :             concat_store_slow:;
    6273            7 :               rtx temp = assign_stack_temp (GET_MODE (to_rtx),
    6274           14 :                                             GET_MODE_SIZE (GET_MODE (to_rtx)));
    6275            7 :               write_complex_part (temp, XEXP (to_rtx, 0), false, true);
    6276            7 :               write_complex_part (temp, XEXP (to_rtx, 1), true, false);
    6277            7 :               result = store_field (temp, bitsize, bitpos,
    6278              :                                     bitregion_start, bitregion_end,
    6279              :                                     mode1, from, get_alias_set (to),
    6280              :                                     nontemporal, reversep);
    6281            7 :               emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
    6282            7 :               emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
    6283              :             }
    6284              :         }
    6285              :       /* For calls to functions returning variable length structures, if TO_RTX
    6286              :          is not a MEM, go through a MEM because we must not create temporaries
    6287              :          of the VLA type.  */
    6288      4652870 :       else if (!MEM_P (to_rtx)
    6289       664671 :                && TREE_CODE (from) == CALL_EXPR
    6290          252 :                && COMPLETE_TYPE_P (TREE_TYPE (from))
    6291      4653122 :                && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
    6292              :         {
    6293            6 :           rtx temp = assign_stack_temp (GET_MODE (to_rtx),
    6294           12 :                                         GET_MODE_SIZE (GET_MODE (to_rtx)));
    6295            6 :           result = store_field (temp, bitsize, bitpos, bitregion_start,
    6296              :                                 bitregion_end, mode1, from, get_alias_set (to),
    6297              :                                 nontemporal, reversep);
    6298            6 :           emit_move_insn (to_rtx, temp);
    6299              :         }
    6300              :       else
    6301              :         {
    6302      4652864 :           if (MEM_P (to_rtx))
    6303              :             {
    6304              :               /* If the field is at offset zero, we could have been given the
    6305              :                  DECL_RTX of the parent struct.  Don't munge it.  */
    6306      3988199 :               to_rtx = shallow_copy_rtx (to_rtx);
    6307      3988199 :               set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
    6308      3988199 :               if (volatilep)
    6309         8697 :                 MEM_VOLATILE_P (to_rtx) = 1;
    6310              :             }
    6311              : 
    6312      4652864 :           gcc_checking_assert (known_ge (bitpos, 0));
    6313      4652864 :           if (optimize_bitfield_assignment_op (bitsize, bitpos,
    6314              :                                                bitregion_start, bitregion_end,
    6315              :                                                mode1, to_rtx, to, from,
    6316              :                                                reversep))
    6317              :             result = NULL;
    6318      4652697 :           else if (SUBREG_P (to_rtx)
    6319      4652697 :                    && SUBREG_PROMOTED_VAR_P (to_rtx))
    6320              :             {
    6321              :               /* If to_rtx is a promoted subreg, we need to zero or sign
    6322              :                  extend the value afterwards.  */
    6323            0 :               if (TREE_CODE (to) == MEM_REF
    6324            0 :                   && TYPE_MODE (TREE_TYPE (from)) != BLKmode
    6325            0 :                   && !REF_REVERSE_STORAGE_ORDER (to)
    6326            0 :                   && known_eq (bitpos, 0)
    6327            0 :                   && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
    6328            0 :                 result = store_expr (from, to_rtx, 0, nontemporal, false);
    6329              :               /* Check if the field overlaps the MSB, requiring extension.  */
    6330            0 :               else if (store_field_updates_msb_p (bitpos, bitsize, to_rtx))
    6331              :                 {
    6332            0 :                   scalar_int_mode imode = subreg_unpromoted_mode (to_rtx);
    6333            0 :                   scalar_int_mode omode = subreg_promoted_mode (to_rtx);
    6334            0 :                   rtx to_rtx1 = lowpart_subreg (imode, SUBREG_REG (to_rtx),
    6335              :                                                 omode);
    6336            0 :                   result = store_field (to_rtx1, bitsize, bitpos,
    6337              :                                         bitregion_start, bitregion_end,
    6338              :                                         mode1, from, get_alias_set (to),
    6339              :                                         nontemporal, reversep);
    6340              :                   /* If the target usually keeps IMODE appropriately
    6341              :                      extended in OMODE it's unsafe to refer to it using
    6342              :                      a SUBREG whilst this invariant doesn't hold.  */
    6343            0 :                   if (targetm.mode_rep_extended (imode, omode) != UNKNOWN)
    6344            0 :                     to_rtx1 = simplify_gen_unary (TRUNCATE, imode,
    6345              :                                                   SUBREG_REG (to_rtx), omode);
    6346            0 :                   convert_move (SUBREG_REG (to_rtx), to_rtx1,
    6347            0 :                                 SUBREG_PROMOTED_SIGN (to_rtx));
    6348              :                 }
    6349              :               else
    6350            0 :                 result = store_field (to_rtx, bitsize, bitpos,
    6351              :                                       bitregion_start, bitregion_end,
    6352              :                                       mode1, from, get_alias_set (to),
    6353              :                                       nontemporal, reversep);
    6354              :             }
    6355              :           else
    6356      4652697 :             result = store_field (to_rtx, bitsize, bitpos,
    6357              :                                   bitregion_start, bitregion_end,
    6358              :                                   mode1, from, get_alias_set (to),
    6359              :                                   nontemporal, reversep);
    6360              :           /* Move the temporary storage back to the non-MEM_P.  */
    6361      4652864 :           if (stemp)
    6362            3 :             emit_move_insn (old_to_rtx, stemp);
    6363              :         }
    6364              : 
    6365      4653024 :       if (result)
    6366       804533 :         preserve_temp_slots (result);
    6367      4653024 :       pop_temp_slots ();
    6368      4653024 :       return;
    6369              :     }
    6370              : 
    6371              :   /* If the rhs is a function call and its value is not an aggregate,
    6372              :      call the function before we start to compute the lhs.
    6373              :      This is needed for correct code for cases such as
    6374              :      val = setjmp (buf) on machines where reference to val
    6375              :      requires loading up part of an address in a separate insn.
    6376              : 
    6377              :      Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
    6378              :      since it might be a promoted variable where the zero- or sign- extension
    6379              :      needs to be done.  Handling this in the normal way is safe because no
    6380              :      computation is done before the call.  The same is true for SSA names.  */
    6381      2315508 :   if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
    6382      2118357 :       && COMPLETE_TYPE_P (TREE_TYPE (from))
    6383      2118357 :       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
    6384     15338919 :       && ! (((VAR_P (to)
    6385              :               || TREE_CODE (to) == PARM_DECL
    6386              :               || TREE_CODE (to) == RESULT_DECL)
    6387       119246 :              && REG_P (DECL_RTL (to)))
    6388      2006934 :             || TREE_CODE (to) == SSA_NAME))
    6389              :     {
    6390         8083 :       rtx value;
    6391              : 
    6392         8083 :       push_temp_slots ();
    6393         8083 :       value = expand_normal (from);
    6394              : 
    6395         8083 :       if (to_rtx == 0)
    6396         8083 :         to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6397              : 
    6398              :       /* Handle calls that return values in multiple non-contiguous locations.
    6399              :          The Irix 6 ABI has examples of this.  */
    6400         8083 :       if (GET_CODE (to_rtx) == PARALLEL)
    6401              :         {
    6402            0 :           if (GET_CODE (value) == PARALLEL)
    6403            0 :             emit_group_move (to_rtx, value);
    6404              :           else
    6405            0 :             emit_group_load (to_rtx, value, TREE_TYPE (from),
    6406            0 :                              int_size_in_bytes (TREE_TYPE (from)));
    6407              :         }
    6408         8083 :       else if (GET_CODE (value) == PARALLEL)
    6409         1829 :         emit_group_store (to_rtx, value, TREE_TYPE (from),
    6410         1829 :                           int_size_in_bytes (TREE_TYPE (from)));
    6411         6254 :       else if (GET_MODE (to_rtx) == BLKmode)
    6412              :         {
    6413              :           /* Handle calls that return BLKmode values in registers.  */
    6414          247 :           if (REG_P (value))
    6415          247 :             copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
    6416              :           else
    6417            0 :             emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
    6418              :         }
    6419              :       else
    6420              :         {
    6421         6007 :           if (POINTER_TYPE_P (TREE_TYPE (to)))
    6422            0 :             value = convert_memory_address_addr_space
    6423            0 :               (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
    6424            0 :                TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
    6425              : 
    6426         6007 :           emit_move_insn (to_rtx, value);
    6427              :         }
    6428              : 
    6429         8083 :       preserve_temp_slots (to_rtx);
    6430         8083 :       pop_temp_slots ();
    6431         8083 :       return;
    6432              :     }
    6433              : 
    6434              :   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.  */
    6435     13212479 :   to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6436              : 
    6437              :   /* Don't move directly into a return register.  */
    6438     13212479 :   if (TREE_CODE (to) == RESULT_DECL
    6439        28852 :       && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
    6440              :     {
    6441            0 :       rtx temp;
    6442              : 
    6443            0 :       push_temp_slots ();
    6444              : 
    6445              :       /* If the source is itself a return value, it still is in a pseudo at
    6446              :          this point so we can move it back to the return register directly.  */
    6447            0 :       if (REG_P (to_rtx)
    6448            0 :           && TYPE_MODE (TREE_TYPE (from)) == BLKmode
    6449            0 :           && TREE_CODE (from) != CALL_EXPR)
    6450            0 :         temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
    6451              :       else
    6452            0 :         temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
    6453              : 
    6454              :       /* Handle calls that return values in multiple non-contiguous locations.
    6455              :          The Irix 6 ABI has examples of this.  */
    6456            0 :       if (GET_CODE (to_rtx) == PARALLEL)
    6457              :         {
    6458            0 :           if (GET_CODE (temp) == PARALLEL)
    6459            0 :             emit_group_move (to_rtx, temp);
    6460              :           else
    6461            0 :             emit_group_load (to_rtx, temp, TREE_TYPE (from),
    6462            0 :                              int_size_in_bytes (TREE_TYPE (from)));
    6463              :         }
    6464            0 :       else if (temp)
    6465            0 :         emit_move_insn (to_rtx, temp);
    6466              : 
    6467            0 :       preserve_temp_slots (to_rtx);
    6468            0 :       pop_temp_slots ();
    6469            0 :       return;
    6470              :     }
    6471              : 
    6472              :   /* In case we are returning the contents of an object which overlaps
    6473              :      the place the value is being stored, use a safe function when copying
    6474              :      a value through a pointer into a structure value return block.  */
    6475     13212479 :   if (TREE_CODE (to) == RESULT_DECL
    6476        28852 :       && TREE_CODE (from) == INDIRECT_REF
    6477            0 :       && ADDR_SPACE_GENERIC_P
    6478              :            (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
    6479            0 :       && refs_may_alias_p (to, from)
    6480            0 :       && cfun->returns_struct
    6481     13212479 :       && !cfun->returns_pcc_struct)
    6482              :     {
    6483            0 :       rtx from_rtx, size;
    6484              : 
    6485            0 :       push_temp_slots ();
    6486            0 :       size = expr_size (from);
    6487            0 :       from_rtx = expand_normal (from);
    6488              : 
    6489            0 :       emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
    6490              : 
    6491            0 :       preserve_temp_slots (to_rtx);
    6492            0 :       pop_temp_slots ();
    6493            0 :       return;
    6494              :     }
    6495              : 
    6496              :   /* Compute FROM and store the value in the rtx we got.  */
    6497              : 
    6498     13212479 :   push_temp_slots ();
    6499     13212479 :   result = store_expr (from, to_rtx, 0, nontemporal, false);
    6500     13212478 :   preserve_temp_slots (result);
    6501     13212478 :   pop_temp_slots ();
    6502     13212478 :   return;
    6503              : }
    6504              : 
    6505              : /* Emits nontemporal store insn that moves FROM to TO.  Returns true if this
    6506              :    succeeded, false otherwise.  */
    6507              : 
    6508              : bool
    6509           17 : emit_storent_insn (rtx to, rtx from)
    6510              : {
    6511           17 :   class expand_operand ops[2];
    6512           17 :   machine_mode mode = GET_MODE (to);
    6513           17 :   enum insn_code code = optab_handler (storent_optab, mode);
    6514              : 
    6515           17 :   if (code == CODE_FOR_nothing)
    6516              :     return false;
    6517              : 
    6518           17 :   create_fixed_operand (&ops[0], to);
    6519           17 :   create_input_operand (&ops[1], from, mode);
    6520           17 :   return maybe_expand_insn (code, 2, ops);
    6521              : }
    6522              : 
    6523              : /* Helper function for store_expr storing of STRING_CST.  */
    6524              : 
    6525              : static rtx
    6526        82179 : string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
    6527              :                      fixed_size_mode mode)
    6528              : {
    6529        82179 :   tree str = (tree) data;
    6530              : 
    6531        82179 :   gcc_assert (offset >= 0);
    6532        82179 :   if (offset >= TREE_STRING_LENGTH (str))
    6533         3428 :     return const0_rtx;
    6534              : 
    6535        78751 :   if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
    6536        78751 :       > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
    6537              :     {
    6538         2552 :       char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
    6539         2552 :       size_t l = TREE_STRING_LENGTH (str) - offset;
    6540         2552 :       memcpy (p, TREE_STRING_POINTER (str) + offset, l);
    6541         2552 :       memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
    6542         2552 :       return c_readstr (p, mode, false);
    6543              :     }
    6544              : 
    6545        76199 :   return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
    6546              : }
    6547              : 
    6548              : /* Helper function for store_expr storing of RAW_DATA_CST.  */
    6549              : 
    6550              : static rtx
    6551           36 : raw_data_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
    6552              :                        fixed_size_mode mode)
    6553              : {
    6554           36 :   tree cst = (tree) data;
    6555              : 
    6556           36 :   gcc_assert (offset >= 0);
    6557           36 :   if (offset >= RAW_DATA_LENGTH (cst))
    6558            0 :     return const0_rtx;
    6559              : 
    6560           36 :   if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
    6561           36 :       > (unsigned HOST_WIDE_INT) RAW_DATA_LENGTH (cst))
    6562              :     {
    6563            0 :       char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
    6564            0 :       size_t l = RAW_DATA_LENGTH (cst) - offset;
    6565            0 :       memcpy (p, RAW_DATA_POINTER (cst) + offset, l);
    6566            0 :       memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
    6567            0 :       return c_readstr (p, mode, false);
    6568              :     }
    6569              : 
    6570           36 :   return c_readstr (RAW_DATA_POINTER (cst) + offset, mode, false);
    6571              : }
    6572              : 
    6573              : /* Generate code for computing expression EXP,
    6574              :    and storing the value into TARGET.
    6575              : 
    6576              :    If the mode is BLKmode then we may return TARGET itself.
    6577              :    It turns out that in BLKmode it doesn't cause a problem.
    6578              :    because C has no operators that could combine two different
    6579              :    assignments into the same BLKmode object with different values
    6580              :    with no sequence point.  Will other languages need this to
    6581              :    be more thorough?
    6582              : 
    6583              :    If CALL_PARAM_P is nonzero, this is a store into a call param on the
    6584              :    stack, and block moves may need to be treated specially.
    6585              : 
    6586              :    If NONTEMPORAL is true, try using a nontemporal store instruction.
    6587              : 
    6588              :    If REVERSE is true, the store is to be done in reverse order.  */
    6589              : 
    6590              : rtx
    6591     17099301 : store_expr (tree exp, rtx target, int call_param_p,
    6592              :             bool nontemporal, bool reverse)
    6593              : {
    6594     17099301 :   rtx temp;
    6595     17099301 :   rtx alt_rtl = NULL_RTX;
    6596     17099301 :   location_t loc = curr_insn_location ();
    6597     17099301 :   bool shortened_string_cst = false;
    6598              : 
    6599     17099301 :   if (VOID_TYPE_P (TREE_TYPE (exp)))
    6600              :     {
    6601              :       /* C++ can generate ?: expressions with a throw expression in one
    6602              :          branch and an rvalue in the other. Here, we resolve attempts to
    6603              :          store the throw expression's nonexistent result.  */
    6604            0 :       gcc_assert (!call_param_p);
    6605            0 :       expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
    6606            0 :       return NULL_RTX;
    6607              :     }
    6608     17099301 :   if (TREE_CODE (exp) == COMPOUND_EXPR)
    6609              :     {
    6610              :       /* Perform first part of compound expression, then assign from second
    6611              :          part.  */
    6612            0 :       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
    6613              :                    call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
    6614            0 :       return store_expr (TREE_OPERAND (exp, 1), target,
    6615            0 :                                      call_param_p, nontemporal, reverse);
    6616              :     }
    6617     17099301 :   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
    6618              :     {
    6619              :       /* For conditional expression, get safe form of the target.  Then
    6620              :          test the condition, doing the appropriate assignment on either
    6621              :          side.  This avoids the creation of unnecessary temporaries.
    6622              :          For non-BLKmode, it is more efficient not to do this.  */
    6623              : 
    6624            0 :       rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
    6625              : 
    6626            0 :       do_pending_stack_adjust ();
    6627            0 :       NO_DEFER_POP;
    6628            0 :       jumpifnot (TREE_OPERAND (exp, 0), lab1,
    6629              :                  profile_probability::uninitialized ());
    6630            0 :       store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
    6631              :                   nontemporal, reverse);
    6632            0 :       emit_jump_insn (targetm.gen_jump (lab2));
    6633            0 :       emit_barrier ();
    6634            0 :       emit_label (lab1);
    6635            0 :       store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
    6636              :                   nontemporal, reverse);
    6637            0 :       emit_label (lab2);
    6638            0 :       OK_DEFER_POP;
    6639              : 
    6640            0 :       return NULL_RTX;
    6641              :     }
    6642     17099301 :   else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
    6643              :     /* If this is a scalar in a register that is stored in a wider mode
    6644              :        than the declared mode, compute the result into its declared mode
    6645              :        and then convert to the wider mode.  Our value is the computed
    6646              :        expression.  */
    6647              :     {
    6648            7 :       rtx inner_target = 0;
    6649            7 :       scalar_int_mode outer_mode = subreg_unpromoted_mode (target);
    6650            7 :       scalar_int_mode inner_mode = subreg_promoted_mode (target);
    6651              : 
    6652              :       /* We can do the conversion inside EXP, which will often result
    6653              :          in some optimizations.  Do the conversion in two steps: first
    6654              :          change the signedness, if needed, then the extend.  But don't
    6655              :          do this if the type of EXP is a subtype of something else
    6656              :          since then the conversion might involve more than just
    6657              :          converting modes.  */
    6658           14 :       if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
    6659            0 :           && TREE_TYPE (TREE_TYPE (exp)) == 0
    6660            7 :           && GET_MODE_PRECISION (outer_mode)
    6661            0 :              == TYPE_PRECISION (TREE_TYPE (exp)))
    6662              :         {
    6663            0 :           if (!SUBREG_CHECK_PROMOTED_SIGN (target,
    6664              :                                           TYPE_UNSIGNED (TREE_TYPE (exp))))
    6665              :             {
    6666              :               /* Some types, e.g. Fortran's logical*4, won't have a signed
    6667              :                  version, so use the mode instead.  */
    6668            0 :               tree ntype
    6669              :                 = (signed_or_unsigned_type_for
    6670            0 :                    (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
    6671            0 :               if (ntype == NULL)
    6672            0 :                 ntype = lang_hooks.types.type_for_mode
    6673            0 :                   (TYPE_MODE (TREE_TYPE (exp)),
    6674            0 :                    SUBREG_PROMOTED_SIGN (target));
    6675              : 
    6676            0 :               exp = fold_convert_loc (loc, ntype, exp);
    6677              :             }
    6678              : 
    6679            0 :           exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
    6680            0 :                                   (inner_mode, SUBREG_PROMOTED_SIGN (target)),
    6681              :                                   exp);
    6682              : 
    6683            0 :           inner_target = SUBREG_REG (target);
    6684              :         }
    6685              : 
    6686            7 :       temp = expand_expr (exp, inner_target, VOIDmode,
    6687              :                           call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
    6688              : 
    6689              : 
    6690              :       /* If TEMP is a VOIDmode constant, use convert_modes to make
    6691              :          sure that we properly convert it.  */
    6692            7 :       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
    6693              :         {
    6694            0 :           temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
    6695            0 :                                 temp, SUBREG_PROMOTED_SIGN (target));
    6696            0 :           temp = convert_modes (inner_mode, outer_mode, temp,
    6697            0 :                                 SUBREG_PROMOTED_SIGN (target));
    6698            0 :         }
    6699            7 :       else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
    6700            0 :         temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
    6701            0 :                               temp, SUBREG_PROMOTED_SIGN (target));
    6702              : 
    6703           21 :       convert_move (SUBREG_REG (target), temp,
    6704            7 :                     SUBREG_PROMOTED_SIGN (target));
    6705              : 
    6706            7 :       return NULL_RTX;
    6707              :     }
    6708     17099294 :   else if ((TREE_CODE (exp) == STRING_CST
    6709     17089583 :             || (TREE_CODE (exp) == MEM_REF
    6710      1314465 :                 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
    6711       427420 :                 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    6712              :                    == STRING_CST
    6713         4385 :                 && integer_zerop (TREE_OPERAND (exp, 1))))
    6714        14096 :            && !nontemporal && !call_param_p
    6715     17113390 :            && MEM_P (target))
    6716              :     {
    6717              :       /* Optimize initialization of an array with a STRING_CST.  */
    6718        14078 :       HOST_WIDE_INT exp_len, str_copy_len;
    6719        14078 :       rtx dest_mem;
    6720        14078 :       tree str = TREE_CODE (exp) == STRING_CST
    6721        14078 :                  ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    6722              : 
    6723        14078 :       exp_len = int_expr_size (exp);
    6724        14078 :       if (exp_len <= 0)
    6725            0 :         goto normal_expr;
    6726              : 
    6727        14078 :       if (TREE_STRING_LENGTH (str) <= 0)
    6728            0 :         goto normal_expr;
    6729              : 
    6730        28156 :       if (can_store_by_pieces (exp_len, string_cst_read_str, (void *) str,
    6731        14078 :                                MEM_ALIGN (target), false))
    6732              :         {
    6733        13898 :           store_by_pieces (target, exp_len, string_cst_read_str, (void *) str,
    6734        13898 :                            MEM_ALIGN (target), false, RETURN_BEGIN);
    6735        13898 :           return NULL_RTX;
    6736              :         }
    6737              : 
    6738          180 :       str_copy_len = TREE_STRING_LENGTH (str);
    6739              : 
    6740              :       /* Trailing NUL bytes in EXP will be handled by the call to
    6741              :          clear_storage, which is more efficient than copying them from
    6742              :          the STRING_CST, so trim those from STR_COPY_LEN.  */
    6743          303 :       while (str_copy_len)
    6744              :         {
    6745          260 :           if (TREE_STRING_POINTER (str)[str_copy_len - 1])
    6746              :             break;
    6747          123 :           str_copy_len--;
    6748              :         }
    6749              : 
    6750          180 :       if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
    6751              :         {
    6752          180 :           str_copy_len += STORE_MAX_PIECES - 1;
    6753          180 :           str_copy_len &= ~(STORE_MAX_PIECES - 1);
    6754              :         }
    6755          180 :       if (str_copy_len >= exp_len)
    6756          129 :         goto normal_expr;
    6757              : 
    6758          102 :       if (!can_store_by_pieces (str_copy_len, string_cst_read_str,
    6759           51 :                                 (void *) str, MEM_ALIGN (target), false))
    6760            2 :         goto normal_expr;
    6761              : 
    6762           49 :       dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
    6763           49 :                                   (void *) str, MEM_ALIGN (target), false,
    6764              :                                   RETURN_END);
    6765           49 :       clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
    6766           49 :                                        exp_len - str_copy_len),
    6767              :                      GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
    6768           49 :       return NULL_RTX;
    6769              :     }
    6770              :   else
    6771              :     {
    6772     17085347 :       rtx tmp_target;
    6773              : 
    6774     17085347 :   normal_expr:
    6775              :       /* If we want to use a nontemporal or a reverse order store, force the
    6776              :          value into a register first.  */
    6777     17085347 :       tmp_target = nontemporal || reverse ? NULL_RTX : target;
    6778     17085347 :       tree rexp = exp;
    6779     17085347 :       if (TREE_CODE (exp) == STRING_CST
    6780           42 :           && tmp_target == target
    6781           42 :           && GET_MODE (target) == BLKmode
    6782     17085389 :           && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
    6783              :         {
    6784           42 :           rtx size = expr_size (exp);
    6785           42 :           if (CONST_INT_P (size)
    6786           42 :               && size != const0_rtx
    6787           84 :               && (UINTVAL (size)
    6788           42 :                   > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
    6789              :             {
    6790              :               /* If the STRING_CST has much larger array type than
    6791              :                  TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
    6792              :                  it into the rodata section as the code later on will use
    6793              :                  memset zero for the remainder anyway.  See PR95052.  */
    6794            2 :               tmp_target = NULL_RTX;
    6795            2 :               rexp = copy_node (exp);
    6796            2 :               tree index
    6797            2 :                 = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
    6798            2 :               TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
    6799              :                                                    index);
    6800            2 :               shortened_string_cst = true;
    6801              :             }
    6802              :         }
    6803     34170694 :       temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
    6804              :                                (call_param_p
    6805              :                                 ? EXPAND_STACK_PARM : EXPAND_NORMAL),
    6806              :                                &alt_rtl, false);
    6807     17085346 :       if (shortened_string_cst)
    6808              :         {
    6809            2 :           gcc_assert (MEM_P (temp));
    6810            2 :           temp = change_address (temp, BLKmode, NULL_RTX);
    6811              :         }
    6812              :     }
    6813              : 
    6814              :   /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
    6815              :      the same as that of TARGET, adjust the constant.  This is needed, for
    6816              :      example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
    6817              :      only a word-sized value.  */
    6818      3515689 :   if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
    6819      2540099 :       && TREE_CODE (exp) != ERROR_MARK
    6820     19625445 :       && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
    6821              :     {
    6822            0 :       gcc_assert (!shortened_string_cst);
    6823            0 :       if (GET_MODE_CLASS (GET_MODE (target))
    6824            0 :           != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
    6825            0 :           && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
    6826              :                        GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
    6827              :         {
    6828            0 :           rtx t = simplify_gen_subreg (GET_MODE (target), temp,
    6829            0 :                                        TYPE_MODE (TREE_TYPE (exp)), 0);
    6830            0 :           if (t)
    6831            0 :             temp = t;
    6832              :         }
    6833            0 :       if (GET_MODE (temp) == VOIDmode)
    6834            0 :         temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
    6835            0 :                               temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
    6836              :     }
    6837              : 
    6838              :   /* If value was not generated in the target, store it there.
    6839              :      Convert the value to TARGET's type first if necessary and emit the
    6840              :      pending incrementations that have been queued when expanding EXP.
    6841              :      Note that we cannot emit the whole queue blindly because this will
    6842              :      effectively disable the POST_INC optimization later.
    6843              : 
    6844              :      If TEMP and TARGET compare equal according to rtx_equal_p, but
    6845              :      one or both of them are volatile memory refs, we have to distinguish
    6846              :      two cases:
    6847              :      - expand_expr has used TARGET.  In this case, we must not generate
    6848              :        another copy.  This can be detected by TARGET being equal according
    6849              :        to == .
    6850              :      - expand_expr has not used TARGET - that means that the source just
    6851              :        happens to have the same RTX form.  Since temp will have been created
    6852              :        by expand_expr, it will compare unequal according to == .
    6853              :        We must generate a copy in this case, to reach the correct number
    6854              :        of volatile memory references.  */
    6855              : 
    6856     17085346 :   if ((! rtx_equal_p (temp, target)
    6857      3052721 :        || (temp != target && (side_effects_p (temp)
    6858        46690 :                               || side_effects_p (target)
    6859        46690 :                               || (MEM_P (temp)
    6860        46213 :                                   && !mems_same_for_tbaa_p (temp, target)))))
    6861     14032629 :       && TREE_CODE (exp) != ERROR_MARK
    6862              :       /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
    6863              :          but TARGET is not valid memory reference, TEMP will differ
    6864              :          from TARGET although it is really the same location.  */
    6865     14032629 :       && !(alt_rtl
    6866      1959281 :            && rtx_equal_p (alt_rtl, target)
    6867            1 :            && !side_effects_p (alt_rtl)
    6868            0 :            && !side_effects_p (target))
    6869              :       /* If there's nothing to copy, don't bother.  Don't call
    6870              :          expr_size unless necessary, because some front-ends (C++)
    6871              :          expr_size-hook must not be given objects that are not
    6872              :          supposed to be bit-copied or bit-initialized.  */
    6873     31117975 :       && expr_size (exp) != const0_rtx)
    6874              :     {
    6875     14032629 :       if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
    6876              :         {
    6877         1376 :           gcc_assert (!shortened_string_cst);
    6878         1376 :           if (GET_MODE (target) == BLKmode)
    6879              :             {
    6880              :               /* Handle calls that return BLKmode values in registers.  */
    6881            2 :               if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
    6882            2 :                 copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
    6883              :               else
    6884            0 :                 store_bit_field (target,
    6885            0 :                                  rtx_to_poly_int64 (expr_size (exp))
    6886            0 :                                  * BITS_PER_UNIT,
    6887              :                                  0, 0, 0, GET_MODE (temp), temp, reverse,
    6888              :                                  false);
    6889              :             }
    6890              :           else
    6891         1374 :             convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
    6892              :         }
    6893              : 
    6894     14031253 :       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
    6895              :         {
    6896              :           /* Handle copying a string constant into an array.  The string
    6897              :              constant may be shorter than the array.  So copy just the string's
    6898              :              actual length, and clear the rest.  First get the size of the data
    6899              :              type of the string, which is actually the size of the target.  */
    6900           42 :           rtx size = expr_size (exp);
    6901              : 
    6902           42 :           if (CONST_INT_P (size)
    6903           42 :               && INTVAL (size) < TREE_STRING_LENGTH (exp))
    6904            0 :             emit_block_move (target, temp, size,
    6905              :                              (call_param_p
    6906              :                               ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    6907              :           else
    6908              :             {
    6909           42 :               machine_mode pointer_mode
    6910           42 :                 = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
    6911           42 :               machine_mode address_mode = get_address_mode (target);
    6912              : 
    6913              :               /* Compute the size of the data to copy from the string.  */
    6914           42 :               tree copy_size
    6915           42 :                 = size_binop_loc (loc, MIN_EXPR,
    6916              :                                   make_tree (sizetype, size),
    6917           42 :                                   size_int (TREE_STRING_LENGTH (exp)));
    6918           42 :               rtx copy_size_rtx
    6919           42 :                 = expand_expr (copy_size, NULL_RTX, VOIDmode,
    6920              :                                (call_param_p
    6921              :                                 ? EXPAND_STACK_PARM : EXPAND_NORMAL));
    6922           42 :               rtx_code_label *label = 0;
    6923              : 
    6924              :               /* Copy that much.  */
    6925          126 :               copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
    6926           42 :                                                TYPE_UNSIGNED (sizetype));
    6927           84 :               emit_block_move (target, temp, copy_size_rtx,
    6928              :                                (call_param_p
    6929              :                                 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    6930              : 
    6931              :               /* Figure out how much is left in TARGET that we have to clear.
    6932              :                  Do all calculations in pointer_mode.  */
    6933           42 :               poly_int64 const_copy_size;
    6934           42 :               if (poly_int_rtx_p (copy_size_rtx, &const_copy_size))
    6935              :                 {
    6936           42 :                   size = plus_constant (address_mode, size, -const_copy_size);
    6937           42 :                   target = adjust_address (target, BLKmode, const_copy_size);
    6938              :                 }
    6939              :               else
    6940              :                 {
    6941            0 :                   size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
    6942              :                                        copy_size_rtx, NULL_RTX, 0,
    6943              :                                        OPTAB_LIB_WIDEN);
    6944              : 
    6945            0 :                   if (GET_MODE (copy_size_rtx) != address_mode)
    6946            0 :                     copy_size_rtx = convert_to_mode (address_mode,
    6947              :                                                      copy_size_rtx,
    6948            0 :                                                      TYPE_UNSIGNED (sizetype));
    6949              : 
    6950            0 :                   target = offset_address (target, copy_size_rtx,
    6951              :                                            highest_pow2_factor (copy_size));
    6952            0 :                   label = gen_label_rtx ();
    6953            0 :                   emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
    6954            0 :                                            GET_MODE (size), 0, label);
    6955              :                 }
    6956              : 
    6957           42 :               if (size != const0_rtx)
    6958            2 :                 clear_storage (target, size, BLOCK_OP_NORMAL);
    6959              : 
    6960           42 :               if (label)
    6961            0 :                 emit_label (label);
    6962              :             }
    6963              :         }
    6964     14031211 :       else if (shortened_string_cst)
    6965            0 :         gcc_unreachable ();
    6966              :       /* Handle calls that return values in multiple non-contiguous locations.
    6967              :          The Irix 6 ABI has examples of this.  */
    6968     14031211 :       else if (GET_CODE (target) == PARALLEL)
    6969              :         {
    6970            0 :           if (GET_CODE (temp) == PARALLEL)
    6971            0 :             emit_group_move (target, temp);
    6972              :           else
    6973            0 :             emit_group_load (target, temp, TREE_TYPE (exp),
    6974            0 :                              int_size_in_bytes (TREE_TYPE (exp)));
    6975              :         }
    6976     14031211 :       else if (GET_CODE (temp) == PARALLEL)
    6977            0 :         emit_group_store (target, temp, TREE_TYPE (exp),
    6978            0 :                           int_size_in_bytes (TREE_TYPE (exp)));
    6979     14031211 :       else if (GET_MODE (temp) == BLKmode)
    6980       596762 :         emit_block_move (target, temp, expr_size (exp),
    6981              :                          (call_param_p
    6982              :                           ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    6983              :       /* If we emit a nontemporal store, there is nothing else to do.  */
    6984     13732830 :       else if (nontemporal && emit_storent_insn (target, temp))
    6985              :         ;
    6986              :       else
    6987              :         {
    6988     13732813 :           if (reverse)
    6989          722 :             temp = flip_storage_order (GET_MODE (target), temp);
    6990     13732813 :           temp = force_operand (temp, target);
    6991     13732813 :           if (temp != target)
    6992     13731326 :             emit_move_insn (target, temp);
    6993              :         }
    6994              :     }
    6995              :   else
    6996      3052717 :     gcc_assert (!shortened_string_cst);
    6997              : 
    6998              :   return NULL_RTX;
    6999              : }
    7000              : 
    7001              : /* Return true if field F of structure TYPE is a flexible array.  */
    7002              : 
    7003              : static bool
    7004      4877807 : flexible_array_member_p (const_tree f, const_tree type)
    7005              : {
    7006      4877807 :   const_tree tf;
    7007              : 
    7008      4877807 :   tf = TREE_TYPE (f);
    7009      4877807 :   return (DECL_CHAIN (f) == NULL
    7010      1076277 :           && TREE_CODE (tf) == ARRAY_TYPE
    7011         2549 :           && TYPE_DOMAIN (tf)
    7012         2549 :           && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
    7013         2549 :           && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
    7014         2549 :           && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
    7015      4877846 :           && int_size_in_bytes (type) >= 0);
    7016              : }
    7017              : 
    7018              : /* If FOR_CTOR_P, return the number of top-level elements that a constructor
    7019              :    must have in order for it to completely initialize a value of type TYPE.
    7020              :    Return -1 if the number isn't known.
    7021              : 
    7022              :    If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE.  */
    7023              : 
    7024              : static HOST_WIDE_INT
    7025      4017713 : count_type_elements (const_tree type, bool for_ctor_p)
    7026              : {
    7027      4017713 :   switch (TREE_CODE (type))
    7028              :     {
    7029       164215 :     case ARRAY_TYPE:
    7030       164215 :       {
    7031       164215 :         tree nelts_minus_one;
    7032              : 
    7033       164215 :         nelts_minus_one = array_type_nelts_minus_one (type);
    7034       164215 :         if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one))
    7035              :           {
    7036       164204 :             unsigned HOST_WIDE_INT n;
    7037              : 
    7038       164204 :             n = tree_to_uhwi (nelts_minus_one) + 1;
    7039       164204 :             if (n == 0 || for_ctor_p)
    7040       163124 :               return n;
    7041              :             else
    7042         1080 :               return n * count_type_elements (TREE_TYPE (type), false);
    7043              :           }
    7044           11 :         return for_ctor_p ? -1 : 1;
    7045              :       }
    7046              : 
    7047      2130475 :     case RECORD_TYPE:
    7048      2130475 :       {
    7049      2130475 :         unsigned HOST_WIDE_INT n;
    7050      2130475 :         tree f;
    7051              : 
    7052      2130475 :         n = 0;
    7053     21318723 :         for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    7054     19188248 :           if (TREE_CODE (f) == FIELD_DECL)
    7055              :             {
    7056      5336263 :               if (!for_ctor_p)
    7057       458456 :                 n += count_type_elements (TREE_TYPE (f), false);
    7058      4877807 :               else if (!flexible_array_member_p (f, type))
    7059              :                 /* Don't count flexible arrays, which are not supposed
    7060              :                    to be initialized.  */
    7061      4877768 :                 n += 1;
    7062              :             }
    7063              : 
    7064      2130475 :         return n;
    7065              :       }
    7066              : 
    7067         3276 :     case UNION_TYPE:
    7068         3276 :     case QUAL_UNION_TYPE:
    7069         3276 :       {
    7070         3276 :         tree f;
    7071         3276 :         HOST_WIDE_INT n, m;
    7072              : 
    7073         3276 :         gcc_assert (!for_ctor_p);
    7074              :         /* Estimate the number of scalars in each field and pick the
    7075              :            maximum.  Other estimates would do instead; the idea is simply
    7076              :            to make sure that the estimate is not sensitive to the ordering
    7077              :            of the fields.  */
    7078         3276 :         n = 1;
    7079        74441 :         for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    7080        71165 :           if (TREE_CODE (f) == FIELD_DECL)
    7081              :             {
    7082        66762 :               m = count_type_elements (TREE_TYPE (f), false);
    7083              :               /* If the field doesn't span the whole union, add an extra
    7084              :                  scalar for the rest.  */
    7085        66762 :               if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
    7086        66762 :                                     TYPE_SIZE (type)) != 1)
    7087        47580 :                 m++;
    7088        66762 :               if (n < m)
    7089        71165 :                 n = m;
    7090              :             }
    7091              :         return n;
    7092              :       }
    7093              : 
    7094              :     case COMPLEX_TYPE:
    7095              :       return 2;
    7096              : 
    7097          309 :     case VECTOR_TYPE:
    7098          309 :       {
    7099          309 :         unsigned HOST_WIDE_INT nelts;
    7100          309 :         if (TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
    7101          309 :           return nelts;
    7102              :         else
    7103              :           return -1;
    7104              :       }
    7105              : 
    7106              :     case INTEGER_TYPE:
    7107              :     case REAL_TYPE:
    7108              :     case FIXED_POINT_TYPE:
    7109              :     case ENUMERAL_TYPE:
    7110              :     case BOOLEAN_TYPE:
    7111              :     case POINTER_TYPE:
    7112              :     case OFFSET_TYPE:
    7113              :     case REFERENCE_TYPE:
    7114              :     case NULLPTR_TYPE:
    7115              :     case OPAQUE_TYPE:
    7116              :     case BITINT_TYPE:
    7117              :       return 1;
    7118              : 
    7119            0 :     case ERROR_MARK:
    7120            0 :       return 0;
    7121              : 
    7122            0 :     case VOID_TYPE:
    7123            0 :     case METHOD_TYPE:
    7124            0 :     case FUNCTION_TYPE:
    7125            0 :     case LANG_TYPE:
    7126            0 :     default:
    7127            0 :       gcc_unreachable ();
    7128              :     }
    7129              : }
    7130              : 
    7131              : /* Helper for categorize_ctor_elements.  Identical interface.  */
    7132              : 
    7133              : static bool
    7134      1489044 : categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
    7135              :                             HOST_WIDE_INT *p_unique_nz_elts,
    7136              :                             HOST_WIDE_INT *p_init_elts, int *p_complete)
    7137              : {
    7138      1489044 :   unsigned HOST_WIDE_INT idx;
    7139      1489044 :   HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
    7140      1489044 :   tree value, purpose, elt_type;
    7141              : 
    7142              :   /* Whether CTOR is a valid constant initializer, in accordance with what
    7143              :      initializer_constant_valid_p does.  If inferred from the constructor
    7144              :      elements, true until proven otherwise.  */
    7145      1489044 :   bool const_from_elts_p = constructor_static_from_elts_p (ctor);
    7146      1489044 :   bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
    7147              : 
    7148      1489044 :   nz_elts = 0;
    7149      1489044 :   unique_nz_elts = 0;
    7150      1489044 :   init_elts = 0;
    7151      1489044 :   num_fields = 0;
    7152      1489044 :   elt_type = NULL_TREE;
    7153              : 
    7154      5726662 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
    7155              :     {
    7156      4237618 :       HOST_WIDE_INT mult = 1;
    7157              : 
    7158      4237618 :       if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
    7159              :         {
    7160          635 :           tree lo_index = TREE_OPERAND (purpose, 0);
    7161          635 :           tree hi_index = TREE_OPERAND (purpose, 1);
    7162              : 
    7163          635 :           if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
    7164          635 :             mult = (tree_to_uhwi (hi_index)
    7165          635 :                     - tree_to_uhwi (lo_index) + 1);
    7166              :         }
    7167      4237618 :       num_fields += mult;
    7168      4237618 :       elt_type = TREE_TYPE (value);
    7169              : 
    7170      4237618 :       switch (TREE_CODE (value))
    7171              :         {
    7172       525229 :         case CONSTRUCTOR:
    7173       525229 :           {
    7174       525229 :             HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
    7175              : 
    7176       525229 :             bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
    7177              :                                                            &ic, p_complete);
    7178              : 
    7179       525229 :             nz_elts += mult * nz;
    7180       525229 :             unique_nz_elts += unz;
    7181       525229 :             init_elts += mult * ic;
    7182              : 
    7183       525229 :             if (const_from_elts_p && const_p)
    7184       312394 :               const_p = const_elt_p;
    7185              :           }
    7186       525229 :           break;
    7187              : 
    7188      2274246 :         case INTEGER_CST:
    7189      2274246 :         case REAL_CST:
    7190      2274246 :         case FIXED_CST:
    7191      2274246 :           if (!initializer_zerop (value))
    7192              :             {
    7193      1651822 :               nz_elts += mult;
    7194      1651822 :               unique_nz_elts++;
    7195              :             }
    7196      2274246 :           init_elts += mult;
    7197      2274246 :           break;
    7198              : 
    7199         6297 :         case STRING_CST:
    7200         6297 :           nz_elts += mult * TREE_STRING_LENGTH (value);
    7201         6297 :           unique_nz_elts += TREE_STRING_LENGTH (value);
    7202         6297 :           init_elts += mult * TREE_STRING_LENGTH (value);
    7203         6297 :           break;
    7204              : 
    7205          160 :         case RAW_DATA_CST:
    7206          160 :           nz_elts += mult * RAW_DATA_LENGTH (value);
    7207          160 :           unique_nz_elts += RAW_DATA_LENGTH (value);
    7208          160 :           init_elts += mult * RAW_DATA_LENGTH (value);
    7209          160 :           num_fields += mult * (RAW_DATA_LENGTH (value) - 1);
    7210          160 :           break;
    7211              : 
    7212         2635 :         case COMPLEX_CST:
    7213         2635 :           if (!initializer_zerop (TREE_REALPART (value)))
    7214              :             {
    7215         2209 :               nz_elts += mult;
    7216         2209 :               unique_nz_elts++;
    7217              :             }
    7218         2635 :           if (!initializer_zerop (TREE_IMAGPART (value)))
    7219              :             {
    7220         2123 :               nz_elts += mult;
    7221         2123 :               unique_nz_elts++;
    7222              :             }
    7223         2635 :           init_elts += 2 * mult;
    7224         2635 :           break;
    7225              : 
    7226          796 :         case VECTOR_CST:
    7227          796 :           {
    7228          796 :             unsigned int nunits
    7229              :               = constant_lower_bound
    7230          796 :               (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value)));
    7231         5347 :             for (unsigned int i = 0; i < nunits; ++i)
    7232              :               {
    7233         4551 :                 tree v = VECTOR_CST_ELT (value, i);
    7234         4551 :                 if (!initializer_zerop (v))
    7235              :                   {
    7236         1993 :                     nz_elts += mult;
    7237         1993 :                     unique_nz_elts++;
    7238              :                   }
    7239         4551 :                 init_elts += mult;
    7240              :               }
    7241              :           }
    7242              :           break;
    7243              : 
    7244      1428255 :         default:
    7245      1428255 :           {
    7246      1428255 :             HOST_WIDE_INT tc = count_type_elements (elt_type, false);
    7247      1428255 :             nz_elts += mult * tc;
    7248      1428255 :             unique_nz_elts += tc;
    7249      1428255 :             init_elts += mult * tc;
    7250              : 
    7251      1428255 :             if (const_from_elts_p && const_p)
    7252       585503 :               const_p
    7253       585503 :                 = initializer_constant_valid_p (value,
    7254              :                                                 elt_type,
    7255       585503 :                                                 TYPE_REVERSE_STORAGE_ORDER
    7256              :                                                 (TREE_TYPE (ctor)))
    7257              :                   != NULL_TREE;
    7258              :           }
    7259              :           break;
    7260              :         }
    7261              :     }
    7262              : 
    7263      1489044 :   if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
    7264              :                                                 num_fields, elt_type))
    7265       175915 :     *p_complete = 0;
    7266      1313129 :   else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
    7267      1313129 :            || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
    7268              :     {
    7269        11746 :       if (*p_complete
    7270         7604 :           && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
    7271        21621 :           && (num_fields
    7272         4939 :               ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
    7273         4936 :                                   TYPE_SIZE (elt_type)) != 1
    7274            3 :               : type_has_padding_at_level_p (TREE_TYPE (ctor))))
    7275         3347 :         *p_complete = 0;
    7276         8399 :       else if (*p_complete > 0
    7277        12318 :                && (num_fields
    7278         3919 :                    ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
    7279         3919 :                                        TYPE_SIZE (elt_type)) != 1
    7280            0 :                    : type_has_padding_at_level_p (TREE_TYPE (ctor))))
    7281          217 :         *p_complete = -1;
    7282              :     }
    7283      1301383 :   else if (*p_complete
    7284      1196157 :            && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
    7285      1177470 :                || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
    7286      1320075 :            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
    7287         2425 :     *p_complete = 0;
    7288      1298958 :   else if (*p_complete > 0
    7289      1298958 :            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
    7290        14337 :     *p_complete = -1;
    7291              : 
    7292      1489044 :   *p_nz_elts += nz_elts;
    7293      1489044 :   *p_unique_nz_elts += unique_nz_elts;
    7294      1489044 :   *p_init_elts += init_elts;
    7295              : 
    7296      1489044 :   return const_p;
    7297              : }
    7298              : 
    7299              : /* Examine CTOR to discover:
    7300              :    * how many scalar fields are set to nonzero values,
    7301              :      and place it in *P_NZ_ELTS;
    7302              :    * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
    7303              :      high - low + 1 (this can be useful for callers to determine ctors
    7304              :      that could be cheaply initialized with - perhaps nested - loops
    7305              :      compared to copied from huge read-only data),
    7306              :      and place it in *P_UNIQUE_NZ_ELTS;
    7307              :    * how many scalar fields in total are in CTOR,
    7308              :      and place it in *P_ELT_COUNT.
    7309              :    * whether the constructor is complete -- in the sense that every
    7310              :      meaningful byte is explicitly given a value --
    7311              :      and place it in *P_COMPLETE:
    7312              :      -  0 if any field is missing
    7313              :      -  1 if all fields are initialized, and there's no padding
    7314              :      - -1 if all fields are initialized, but there's padding
    7315              : 
    7316              :    Return whether or not CTOR is a valid static constant initializer, the same
    7317              :    as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0".  */
    7318              : 
    7319              : bool
    7320       963815 : categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
    7321              :                           HOST_WIDE_INT *p_unique_nz_elts,
    7322              :                           HOST_WIDE_INT *p_init_elts, int *p_complete)
    7323              : {
    7324       963815 :   *p_nz_elts = 0;
    7325       963815 :   *p_unique_nz_elts = 0;
    7326       963815 :   *p_init_elts = 0;
    7327       963815 :   *p_complete = 1;
    7328              : 
    7329       963815 :   return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
    7330       963815 :                                      p_init_elts, p_complete);
    7331              : }
    7332              : 
    7333              : /* Return true if constructor CTOR is simple enough to be materialized
    7334              :    in an integer mode register.  Limit the size to WORDS words, which
    7335              :    is 1 by default.  */
    7336              : 
    7337              : bool
    7338        21529 : immediate_const_ctor_p (const_tree ctor, unsigned int words)
    7339              : {
    7340              :   /* Allow function to be called with a VAR_DECL's DECL_INITIAL.  */
    7341        21529 :   if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
    7342              :     return false;
    7343              : 
    7344         2790 :   return TREE_CONSTANT (ctor)
    7345         2790 :          && !TREE_ADDRESSABLE (ctor)
    7346         2779 :          && CONSTRUCTOR_NELTS (ctor)
    7347         2755 :          && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
    7348          627 :          && int_expr_size (ctor) <= words * UNITS_PER_WORD
    7349         2976 :          && initializer_constant_valid_for_bitfield_p (ctor);
    7350              : }
    7351              : 
    7352              : /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
    7353              :    of which had type LAST_TYPE.  Each element was itself a complete
    7354              :    initializer, in the sense that every meaningful byte was explicitly
    7355              :    given a value.  Return true if the same is true for the constructor
    7356              :    as a whole.  */
    7357              : 
    7358              : bool
    7359      2071909 : complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
    7360              :                           const_tree last_type)
    7361              : {
    7362      2071909 :   if (TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE)
    7363              :     {
    7364         8749 :       if (num_elts == 0)
    7365              :         {
    7366           13 :           if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
    7367              :             return false;
    7368              : 
    7369              :           /* If the CONSTRUCTOR doesn't have any elts, it is
    7370              :              incomplete if the union has at least one field.  */
    7371           16 :           for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
    7372           13 :             if (TREE_CODE (f) == FIELD_DECL)
    7373              :               return false;
    7374              : 
    7375              :           return true;
    7376              :         }
    7377              : 
    7378         8736 :       gcc_assert (num_elts == 1 && last_type);
    7379              : 
    7380         8736 :       if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
    7381              :         /* ??? We could look at each element of the union, and find the
    7382              :            largest element.  Which would avoid comparing the size of the
    7383              :            initialized element against any tail padding in the union.
    7384              :            Doesn't seem worth the effort...  */
    7385            6 :         return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
    7386              : 
    7387              :       return true;
    7388              :     }
    7389              : 
    7390      2063160 :   return count_type_elements (type, true) == num_elts;
    7391              : }
    7392              : 
    7393              : /* Return true if EXP contains mostly (3/4) zeros.  */
    7394              : 
    7395              : static bool
    7396       348027 : mostly_zeros_p (const_tree exp)
    7397              : {
    7398       348027 :   if (TREE_CODE (exp) == CONSTRUCTOR)
    7399              :     {
    7400          130 :       HOST_WIDE_INT nz_elts, unz_elts, init_elts;
    7401          130 :       int complete_p;
    7402              : 
    7403          130 :       categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
    7404              :                                 &complete_p);
    7405          130 :       return !complete_p || nz_elts < init_elts / 4;
    7406              :     }
    7407              : 
    7408       347897 :   return initializer_zerop (exp);
    7409              : }
    7410              : 
    7411              : /* Return true if EXP contains all zeros.  */
    7412              : 
    7413              : static bool
    7414          931 : all_zeros_p (const_tree exp)
    7415              : {
    7416          931 :   if (TREE_CODE (exp) == CONSTRUCTOR)
    7417              :     {
    7418          931 :       HOST_WIDE_INT nz_elts, unz_elts, init_elts;
    7419          931 :       int complete_p;
    7420              : 
    7421          931 :       categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
    7422              :                                 &complete_p);
    7423          931 :       return nz_elts == 0;
    7424              :     }
    7425              : 
    7426            0 :   return initializer_zerop (exp);
    7427              : }
    7428              : 
    7429              : /* Helper function for store_constructor.
    7430              :    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
    7431              :    CLEARED is as for store_constructor.
    7432              :    ALIAS_SET is the alias set to use for any stores.
    7433              :    If REVERSE is true, the store is to be done in reverse order.
    7434              : 
    7435              :    This provides a recursive shortcut back to store_constructor when it isn't
    7436              :    necessary to go through store_field.  This is so that we can pass through
    7437              :    the cleared field to let store_constructor know that we may not have to
    7438              :    clear a substructure if the outer structure has already been cleared.  */
    7439              : 
    7440              : static void
    7441        32796 : store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
    7442              :                          poly_uint64 bitregion_start,
    7443              :                          poly_uint64 bitregion_end,
    7444              :                          machine_mode mode,
    7445              :                          tree exp, int cleared,
    7446              :                          alias_set_type alias_set, bool reverse)
    7447              : {
    7448        32796 :   poly_int64 bytepos;
    7449        32796 :   poly_uint64 bytesize;
    7450        32796 :   if (TREE_CODE (exp) == CONSTRUCTOR
    7451              :       /* We can only call store_constructor recursively if the size and
    7452              :          bit position are on a byte boundary.  */
    7453           64 :       && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
    7454           64 :       && maybe_ne (bitsize, 0U)
    7455        32796 :       && multiple_p (bitsize, BITS_PER_UNIT, &bytesize)
    7456              :       /* If we have a nonzero bitpos for a register target, then we just
    7457              :          let store_field do the bitfield handling.  This is unlikely to
    7458              :          generate unnecessary clear instructions anyways.  */
    7459        32860 :       && (known_eq (bitpos, 0) || MEM_P (target)))
    7460              :     {
    7461           64 :       if (MEM_P (target))
    7462              :         {
    7463           22 :           machine_mode target_mode = GET_MODE (target);
    7464           22 :           if (target_mode != BLKmode
    7465           22 :               && !multiple_p (bitpos, GET_MODE_ALIGNMENT (target_mode)))
    7466              :             target_mode = BLKmode;
    7467           22 :           target = adjust_address (target, target_mode, bytepos);
    7468              :         }
    7469              : 
    7470              : 
    7471              :       /* Update the alias set, if required.  */
    7472           22 :       if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
    7473           86 :           && MEM_ALIAS_SET (target) != 0)
    7474              :         {
    7475           18 :           target = copy_rtx (target);
    7476           18 :           set_mem_alias_set (target, alias_set);
    7477              :         }
    7478              : 
    7479           64 :       store_constructor (exp, target, cleared, bytesize, reverse);
    7480              :     }
    7481              :   else
    7482        32732 :     store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
    7483              :                  exp, alias_set, false, reverse);
    7484        32796 : }
    7485              : 
    7486              : 
    7487              : /* Returns the number of FIELD_DECLs in TYPE.  */
    7488              : 
    7489              : static int
    7490        66254 : fields_length (const_tree type)
    7491              : {
    7492        66254 :   tree t = TYPE_FIELDS (type);
    7493        66254 :   int count = 0;
    7494              : 
    7495       747859 :   for (; t; t = DECL_CHAIN (t))
    7496       681605 :     if (TREE_CODE (t) == FIELD_DECL)
    7497       293731 :       ++count;
    7498              : 
    7499        66254 :   return count;
    7500              : }
    7501              : 
    7502              : 
    7503              : /* Store the value of constructor EXP into the rtx TARGET.
    7504              :    TARGET is either a REG or a MEM; we know it cannot conflict, since
    7505              :    safe_from_p has been called.
    7506              :    CLEARED is true if TARGET is known to have been zero'd.
    7507              :    SIZE is the number of bytes of TARGET we are allowed to modify: this
    7508              :    may not be the same as the size of EXP if we are assigning to a field
    7509              :    which has been packed to exclude padding bits.
    7510              :    If REVERSE is true, the store is to be done in reverse order.  */
    7511              : 
    7512              : void
    7513       239825 : store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
    7514              :                    bool reverse)
    7515              : {
    7516       239825 :   tree type = TREE_TYPE (exp);
    7517       239825 :   HOST_WIDE_INT exp_size = int_size_in_bytes (type);
    7518       239825 :   poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
    7519              : 
    7520       239825 :   switch (TREE_CODE (type))
    7521              :     {
    7522        66644 :     case RECORD_TYPE:
    7523        66644 :     case UNION_TYPE:
    7524        66644 :     case QUAL_UNION_TYPE:
    7525        66644 :       {
    7526        66644 :         unsigned HOST_WIDE_INT idx;
    7527        66644 :         tree field, value;
    7528              : 
    7529              :         /* The storage order is specified for every aggregate type.  */
    7530        66644 :         reverse = TYPE_REVERSE_STORAGE_ORDER (type);
    7531              : 
    7532              :         /* If size is zero or the target is already cleared, do nothing.  */
    7533        66644 :         if (known_eq (size, 0) || cleared)
    7534              :           cleared = 1;
    7535              :         /* We either clear the aggregate or indicate the value is dead.  */
    7536        66644 :         else if ((TREE_CODE (type) == UNION_TYPE
    7537        66644 :                   || TREE_CODE (type) == QUAL_UNION_TYPE)
    7538        66883 :                  && ! CONSTRUCTOR_ELTS (exp))
    7539              :           /* If the constructor is empty, clear the union.  */
    7540              :           {
    7541          190 :             clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
    7542          190 :             cleared = 1;
    7543              :           }
    7544              : 
    7545              :         /* If we are building a static constructor into a register,
    7546              :            set the initial value as zero so we can fold the value into
    7547              :            a constant.  But if more than one register is involved,
    7548              :            this probably loses.  */
    7549         4126 :         else if (REG_P (target) && TREE_STATIC (exp)
    7550        66978 :                  && known_le (GET_MODE_SIZE (GET_MODE (target)),
    7551              :                               REGMODE_NATURAL_SIZE (GET_MODE (target))))
    7552              :           {
    7553          200 :             emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
    7554          200 :             cleared = 1;
    7555              :           }
    7556              : 
    7557              :         /* If the constructor has fewer fields than the structure or
    7558              :            if we are initializing the structure to mostly zeros, clear
    7559              :            the whole structure first.  Don't do this if TARGET is a
    7560              :            register whose mode size isn't equal to SIZE since
    7561              :            clear_storage can't handle this case.  */
    7562        66254 :         else if (known_size_p (size)
    7563        66356 :                  && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
    7564           89 :                      || mostly_zeros_p (exp))
    7565       132423 :                  && (!REG_P (target)
    7566         7848 :                      || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
    7567              :           {
    7568        76823 :             clear_storage (target, gen_int_mode (size, Pmode),
    7569              :                            BLOCK_OP_NORMAL);
    7570        66169 :             cleared = 1;
    7571              :           }
    7572              : 
    7573        66644 :         if (REG_P (target) && !cleared)
    7574            2 :           emit_clobber (target);
    7575              : 
    7576              :         /* Store each element of the constructor into the
    7577              :            corresponding field of TARGET.  */
    7578        66889 :         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
    7579              :           {
    7580          245 :             machine_mode mode;
    7581          245 :             HOST_WIDE_INT bitsize;
    7582          245 :             HOST_WIDE_INT bitpos = 0;
    7583          245 :             tree offset;
    7584          245 :             rtx to_rtx = target;
    7585              : 
    7586              :             /* Just ignore missing fields.  We cleared the whole
    7587              :                structure, above, if any fields are missing.  */
    7588          245 :             if (field == 0)
    7589          245 :               continue;
    7590              : 
    7591          245 :             if (cleared && initializer_zerop (value))
    7592            5 :               continue;
    7593              : 
    7594              :             /* Variable sized arrays are ignored.  */
    7595          240 :             tree decl_size = DECL_SIZE (field);
    7596          240 :             if (!decl_size)
    7597            4 :               continue;
    7598              : 
    7599          236 :             if (tree_fits_uhwi_p (decl_size))
    7600          236 :               bitsize = tree_to_uhwi (decl_size);
    7601              :             else
    7602            0 :               gcc_unreachable ();
    7603              : 
    7604          236 :             mode = DECL_MODE (field);
    7605          236 :             if (DECL_BIT_FIELD (field))
    7606           24 :               mode = VOIDmode;
    7607              : 
    7608          236 :             offset = DECL_FIELD_OFFSET (field);
    7609          236 :             if (tree_fits_shwi_p (offset)
    7610          236 :                 && tree_fits_shwi_p (bit_position (field)))
    7611              :               {
    7612          236 :                 bitpos = int_bit_position (field);
    7613          236 :                 offset = NULL_TREE;
    7614              :               }
    7615              :             else
    7616            0 :               gcc_unreachable ();
    7617              : 
    7618              :             /* If this initializes a field that is smaller than a
    7619              :                word, at the start of a word, try to widen it to a full
    7620              :                word.  This special case allows us to output C++ member
    7621              :                function initializations in a form that the optimizers
    7622              :                can understand.  */
    7623          236 :             if (WORD_REGISTER_OPERATIONS
    7624              :                 && REG_P (target)
    7625              :                 && bitsize < BITS_PER_WORD
    7626              :                 && bitpos % BITS_PER_WORD == 0
    7627              :                 && GET_MODE_CLASS (mode) == MODE_INT
    7628              :                 && TREE_CODE (value) == INTEGER_CST
    7629              :                 && exp_size >= 0
    7630              :                 && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
    7631              :               {
    7632              :                 type = TREE_TYPE (value);
    7633              : 
    7634              :                 if (TYPE_PRECISION (type) < BITS_PER_WORD)
    7635              :                   {
    7636              :                     type = lang_hooks.types.type_for_mode
    7637              :                       (word_mode, TYPE_UNSIGNED (type));
    7638              :                     value = fold_convert (type, value);
    7639              :                     /* Make sure the bits beyond the original bitsize are zero
    7640              :                        so that we can correctly avoid extra zeroing stores in
    7641              :                        later constructor elements.  */
    7642              :                     tree bitsize_mask
    7643              :                       = wide_int_to_tree (type, wi::mask (bitsize, false,
    7644              :                                                            BITS_PER_WORD));
    7645              :                     value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
    7646              :                   }
    7647              : 
    7648              :                 if (BYTES_BIG_ENDIAN)
    7649              :                   value
    7650              :                    = fold_build2 (LSHIFT_EXPR, type, value,
    7651              :                                    build_int_cst (type,
    7652              :                                                   BITS_PER_WORD - bitsize));
    7653              :                 bitsize = BITS_PER_WORD;
    7654              :                 mode = word_mode;
    7655              :               }
    7656              : 
    7657          121 :             if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
    7658          357 :                 && DECL_NONADDRESSABLE_P (field))
    7659              :               {
    7660            0 :                 to_rtx = copy_rtx (to_rtx);
    7661            0 :                 MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
    7662              :               }
    7663              : 
    7664          236 :             store_constructor_field (to_rtx, bitsize, bitpos,
    7665          236 :                                      0, bitregion_end, mode,
    7666              :                                      value, cleared,
    7667          236 :                                      get_alias_set (TREE_TYPE (field)),
    7668              :                                      reverse);
    7669              :           }
    7670              :         break;
    7671              :       }
    7672        38555 :     case ARRAY_TYPE:
    7673        38555 :       {
    7674        38555 :         tree value, index;
    7675        38555 :         unsigned HOST_WIDE_INT i, j = 0;
    7676        38555 :         bool need_to_clear;
    7677        38555 :         tree domain;
    7678        38555 :         tree elttype = TREE_TYPE (type);
    7679        38555 :         bool const_bounds_p;
    7680        38555 :         unsigned HOST_WIDE_INT minelt = 0;
    7681        38555 :         unsigned HOST_WIDE_INT maxelt = 0;
    7682              : 
    7683              :         /* The storage order is specified for every aggregate type.  */
    7684        38555 :         reverse = TYPE_REVERSE_STORAGE_ORDER (type);
    7685              : 
    7686        38555 :         domain = TYPE_DOMAIN (type);
    7687        38555 :         const_bounds_p = (TYPE_MIN_VALUE (domain)
    7688        38555 :                           && TYPE_MAX_VALUE (domain)
    7689        38555 :                           && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain))
    7690        77110 :                           && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain)));
    7691              : 
    7692              :         /* If we have constant bounds for the range of the type, get them.  */
    7693        38555 :         if (const_bounds_p)
    7694              :           {
    7695        38555 :             minelt = tree_to_uhwi (TYPE_MIN_VALUE (domain));
    7696        38555 :             maxelt = tree_to_uhwi (TYPE_MAX_VALUE (domain));
    7697              :           }
    7698              : 
    7699              :         /* If the constructor has fewer elements than the array, clear
    7700              :            the whole array first.  Similarly if this is static
    7701              :            constructor of a non-BLKmode object.  */
    7702        38555 :         if (cleared)
    7703              :           need_to_clear = false;
    7704        38509 :         else if (REG_P (target) && TREE_STATIC (exp))
    7705              :           need_to_clear = true;
    7706              :         else
    7707              :           {
    7708        38406 :             unsigned HOST_WIDE_INT idx;
    7709        38406 :             unsigned HOST_WIDE_INT count = 0, zero_count = 0;
    7710        38406 :             need_to_clear = ! const_bounds_p;
    7711              : 
    7712              :             /* This loop is a more accurate version of the loop in
    7713              :                mostly_zeros_p (it handles RANGE_EXPR in an index).  It
    7714              :                is also needed to check for missing elements.  */
    7715        38454 :             FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
    7716              :               {
    7717           48 :                 unsigned HOST_WIDE_INT this_node_count;
    7718              : 
    7719           48 :                 if (need_to_clear)
    7720              :                   break;
    7721              : 
    7722           48 :                 if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
    7723              :                   {
    7724            0 :                     tree lo_index = TREE_OPERAND (index, 0);
    7725            0 :                     tree hi_index = TREE_OPERAND (index, 1);
    7726              : 
    7727            0 :                     if (! tree_fits_uhwi_p (lo_index)
    7728            0 :                         || ! tree_fits_uhwi_p (hi_index))
    7729              :                       {
    7730              :                         need_to_clear = true;
    7731              :                         break;
    7732              :                       }
    7733              : 
    7734            0 :                     this_node_count = (tree_to_uhwi (hi_index)
    7735            0 :                                        - tree_to_uhwi (lo_index) + 1);
    7736            0 :                   }
    7737           48 :                 else if (TREE_CODE (value) == RAW_DATA_CST)
    7738            0 :                   this_node_count = RAW_DATA_LENGTH (value);
    7739              :                 else
    7740              :                   this_node_count = 1;
    7741              : 
    7742           48 :                 count += this_node_count;
    7743           48 :                 if (mostly_zeros_p (value))
    7744            0 :                   zero_count += this_node_count;
    7745              :               }
    7746              : 
    7747              :             /* Clear the entire array first if there are any missing
    7748              :                elements, or if the incidence of zero elements is >=
    7749              :                75%.  */
    7750        38406 :             if (! need_to_clear
    7751        38406 :                 && (count < maxelt - minelt + 1
    7752            6 :                     || 4 * zero_count >= 3 * count))
    7753              :               need_to_clear = true;
    7754              :           }
    7755              : 
    7756        38503 :         if (need_to_clear && maybe_gt (size, 0))
    7757              :           {
    7758        38503 :             if (REG_P (target))
    7759         1588 :               emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
    7760              :             else
    7761        41674 :               clear_storage (target, gen_int_mode (size, Pmode),
    7762              :                              BLOCK_OP_NORMAL);
    7763              :             cleared = 1;
    7764              :           }
    7765              : 
    7766           52 :         if (!cleared && REG_P (target))
    7767              :           /* Inform later passes that the old value is dead.  */
    7768            0 :           emit_clobber (target);
    7769              : 
    7770              :         /* Store each element of the constructor into the
    7771              :            corresponding element of TARGET, determined by counting the
    7772              :            elements.  */
    7773        39711 :         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
    7774              :           {
    7775         1156 :             machine_mode mode;
    7776         1156 :             poly_int64 bitsize;
    7777         1156 :             HOST_WIDE_INT bitpos;
    7778         1156 :             rtx xtarget = target;
    7779              : 
    7780         1156 :             if (cleared && initializer_zerop (value))
    7781              :               {
    7782          672 :                 if (TREE_CODE (value) == RAW_DATA_CST)
    7783            0 :                   j += RAW_DATA_LENGTH (value) - 1;
    7784          674 :                 continue;
    7785              :               }
    7786              : 
    7787          484 :             mode = TYPE_MODE (elttype);
    7788          484 :             if (mode != BLKmode)
    7789          968 :               bitsize = GET_MODE_BITSIZE (mode);
    7790            0 :             else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
    7791            0 :               bitsize = -1;
    7792              : 
    7793          484 :             if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
    7794              :               {
    7795            0 :                 tree lo_index = TREE_OPERAND (index, 0);
    7796            0 :                 tree hi_index = TREE_OPERAND (index, 1);
    7797            0 :                 rtx index_r;
    7798            0 :                 unsigned HOST_WIDE_INT lo, hi, count;
    7799            0 :                 tree offset;
    7800              : 
    7801            0 :                 gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
    7802              : 
    7803              :                 /* If the range is constant and "small", unroll the loop.  */
    7804            0 :                 if (const_bounds_p
    7805            0 :                     && tree_fits_uhwi_p (lo_index)
    7806            0 :                     && tree_fits_uhwi_p (hi_index)
    7807            0 :                     && (lo = tree_to_uhwi (lo_index),
    7808            0 :                         hi = tree_to_uhwi (hi_index),
    7809            0 :                         count = hi - lo + 1,
    7810            0 :                         (!MEM_P (target)
    7811            0 :                          || count <= 2
    7812            0 :                          || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
    7813            0 :                              && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
    7814              :                                  <= 40 * 8)))))
    7815              :                   {
    7816            0 :                     lo -= minelt;  hi -= minelt;
    7817            0 :                     for (; lo <= hi; lo++)
    7818              :                       {
    7819            0 :                         bitpos = lo * tree_to_uhwi (TYPE_SIZE (elttype));
    7820              : 
    7821            0 :                         if (MEM_P (target)
    7822            0 :                             && !MEM_KEEP_ALIAS_SET_P (target)
    7823            0 :                             && TREE_CODE (type) == ARRAY_TYPE
    7824            0 :                             && TYPE_NONALIASED_COMPONENT (type))
    7825              :                           {
    7826            0 :                             target = copy_rtx (target);
    7827            0 :                             MEM_KEEP_ALIAS_SET_P (target) = 1;
    7828              :                           }
    7829              : 
    7830            0 :                         store_constructor_field
    7831            0 :                           (target, bitsize, bitpos, 0, bitregion_end,
    7832              :                            mode, value, cleared,
    7833              :                            get_alias_set (elttype), reverse);
    7834              :                       }
    7835              :                   }
    7836              :                 else
    7837              :                   {
    7838            0 :                     rtx_code_label *loop_start = gen_label_rtx ();
    7839            0 :                     rtx_code_label *loop_end = gen_label_rtx ();
    7840            0 :                     tree exit_cond;
    7841              : 
    7842            0 :                     expand_normal (hi_index);
    7843              : 
    7844            0 :                     index = build_decl (EXPR_LOCATION (exp),
    7845              :                                         VAR_DECL, NULL_TREE, domain);
    7846            0 :                     index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
    7847            0 :                     SET_DECL_RTL (index, index_r);
    7848            0 :                     store_expr (lo_index, index_r, 0, false, reverse);
    7849              : 
    7850              :                     /* Build the head of the loop.  */
    7851            0 :                     do_pending_stack_adjust ();
    7852            0 :                     emit_label (loop_start);
    7853              : 
    7854              :                     /* Assign value to element index.  */
    7855            0 :                     offset = fold_build2 (MINUS_EXPR,
    7856              :                                           TREE_TYPE (index),
    7857              :                                           index,
    7858              :                                           TYPE_MIN_VALUE (domain));
    7859              : 
    7860            0 :                     offset = size_binop (MULT_EXPR,
    7861              :                                          fold_convert (sizetype, offset),
    7862              :                                          TYPE_SIZE_UNIT (elttype));
    7863              : 
    7864            0 :                     xtarget = offset_address (target,
    7865              :                                               expand_normal (offset),
    7866              :                                               highest_pow2_factor (offset));
    7867            0 :                     xtarget = adjust_address (xtarget, mode, 0);
    7868            0 :                     if (TREE_CODE (value) == CONSTRUCTOR)
    7869            0 :                       store_constructor (value, xtarget, cleared,
    7870              :                                          exact_div (bitsize, BITS_PER_UNIT),
    7871              :                                          reverse);
    7872              :                     else
    7873            0 :                       store_expr (value, xtarget, 0, false, reverse);
    7874              : 
    7875              :                     /* Generate a conditional jump to exit the loop.  */
    7876            0 :                     exit_cond = build2 (LT_EXPR, integer_type_node,
    7877              :                                         index, hi_index);
    7878            0 :                     jumpif (exit_cond, loop_end,
    7879              :                             profile_probability::uninitialized ());
    7880              : 
    7881              :                     /* Update the loop counter, and jump to the head of
    7882              :                        the loop.  */
    7883            0 :                     expand_assignment (index,
    7884            0 :                                        build2 (PLUS_EXPR, TREE_TYPE (index),
    7885              :                                                index, integer_one_node),
    7886              :                                        false);
    7887              : 
    7888            0 :                     emit_jump (loop_start);
    7889              : 
    7890              :                     /* Build the end of the loop.  */
    7891            0 :                     emit_label (loop_end);
    7892              :                   }
    7893              :               }
    7894          484 :             else if ((index && !tree_fits_uhwi_p (index))
    7895          484 :                      || !tree_fits_uhwi_p (TYPE_SIZE (elttype)))
    7896              :               {
    7897            0 :                 tree offset;
    7898              : 
    7899            0 :                 gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
    7900            0 :                 if (index)
    7901            0 :                   offset = fold_build2 (MINUS_EXPR,
    7902              :                                         TREE_TYPE (index),
    7903              :                                         index,
    7904              :                                         TYPE_MIN_VALUE (domain));
    7905              :                 else
    7906            0 :                   offset = size_int (i + j);
    7907              : 
    7908            0 :                 offset = size_binop (MULT_EXPR,
    7909              :                                      fold_convert (sizetype, offset),
    7910              :                                      TYPE_SIZE_UNIT (elttype));
    7911            0 :                 xtarget = offset_address (target,
    7912              :                                           expand_normal (offset),
    7913              :                                           highest_pow2_factor (offset));
    7914            0 :                 xtarget = adjust_address (xtarget, mode, 0);
    7915            0 :                 store_expr (value, xtarget, 0, false, reverse);
    7916              :               }
    7917              :             else
    7918              :               {
    7919          484 :                 if (index)
    7920          968 :                   bitpos = ((tree_to_uhwi (index) - minelt)
    7921          484 :                             * tree_to_uhwi (TYPE_SIZE (elttype)));
    7922              :                 else
    7923            0 :                   bitpos = ((i + j) * tree_to_uhwi (TYPE_SIZE (elttype)));
    7924              : 
    7925           52 :                 if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
    7926           52 :                     && TREE_CODE (type) == ARRAY_TYPE
    7927          536 :                     && TYPE_NONALIASED_COMPONENT (type))
    7928              :                   {
    7929            0 :                     target = copy_rtx (target);
    7930            0 :                     MEM_KEEP_ALIAS_SET_P (target) = 1;
    7931              :                   }
    7932          484 :                 if (TREE_CODE (value) != RAW_DATA_CST)
    7933          480 :                   store_constructor_field (target, bitsize, bitpos, 0,
    7934          480 :                                            bitregion_end, mode, value,
    7935              :                                            cleared, get_alias_set (elttype),
    7936              :                                            reverse);
    7937              :                 else
    7938              :                   {
    7939            4 :                     j += RAW_DATA_LENGTH (value) - 1;
    7940            4 :                     gcc_assert (known_eq (bitsize, BITS_PER_UNIT));
    7941            4 :                     rtx to_rtx = adjust_address (target, mode,
    7942              :                                                  bitpos / BITS_PER_UNIT);
    7943              : 
    7944            4 :                     if (to_rtx == target)
    7945            0 :                       to_rtx = copy_rtx (to_rtx);
    7946              : 
    7947            4 :                     if (!MEM_KEEP_ALIAS_SET_P (to_rtx)
    7948            8 :                         && MEM_ALIAS_SET (to_rtx) != 0)
    7949            0 :                       set_mem_alias_set (to_rtx, get_alias_set (elttype));
    7950              : 
    7951            8 :                     if (can_store_by_pieces (RAW_DATA_LENGTH (value),
    7952              :                                              raw_data_cst_read_str,
    7953              :                                              (void *) value,
    7954            4 :                                              MEM_ALIGN (target), false))
    7955              :                       {
    7956            4 :                         store_by_pieces (target, RAW_DATA_LENGTH (value),
    7957              :                                          raw_data_cst_read_str, (void *) value,
    7958            2 :                                          MEM_ALIGN (target), false,
    7959              :                                          RETURN_BEGIN);
    7960            2 :                         continue;
    7961              :                       }
    7962              : 
    7963            2 :                     elttype
    7964            2 :                       = build_array_type_nelts (TREE_TYPE (value),
    7965            2 :                                                 RAW_DATA_LENGTH (value));
    7966            2 :                     tree ctor = build_constructor_single (elttype, NULL_TREE,
    7967              :                                                           value);
    7968            2 :                     ctor = tree_output_constant_def (ctor);
    7969            2 :                     mode = TYPE_MODE (type);
    7970            2 :                     store_constructor_field (target,
    7971            2 :                                              bitsize * RAW_DATA_LENGTH (value),
    7972            2 :                                              bitpos, 0, bitregion_end, mode,
    7973              :                                              ctor, cleared,
    7974              :                                              get_alias_set (elttype), reverse);
    7975              :                   }
    7976              :               }
    7977              :           }
    7978              :         break;
    7979              :       }
    7980              : 
    7981       134626 :     case VECTOR_TYPE:
    7982       134626 :       {
    7983       134626 :         unsigned HOST_WIDE_INT idx;
    7984       134626 :         constructor_elt *ce;
    7985       134626 :         bool need_to_clear;
    7986       134626 :         insn_code icode = CODE_FOR_nothing;
    7987       134626 :         tree elt;
    7988       134626 :         tree elttype = TREE_TYPE (type);
    7989       134626 :         int elt_size = vector_element_bits (type);
    7990       134626 :         machine_mode eltmode = TYPE_MODE (elttype);
    7991       134626 :         poly_int64 bitsize;
    7992       134626 :         poly_int64 bitpos;
    7993       134626 :         rtvec vector = NULL;
    7994       134626 :         poly_uint64 n_elts;
    7995       134626 :         unsigned HOST_WIDE_INT const_n_elts;
    7996       134626 :         alias_set_type alias;
    7997       134626 :         bool vec_vec_init_p = false;
    7998       134626 :         machine_mode mode = GET_MODE (target);
    7999              : 
    8000       134626 :         gcc_assert (eltmode != BLKmode);
    8001              : 
    8002              :         /* Try using vec_duplicate_optab for uniform vectors.  */
    8003       134626 :         icode = optab_handler (vec_duplicate_optab, mode);
    8004       134626 :         if (!TREE_SIDE_EFFECTS (exp)
    8005       134626 :             && VECTOR_MODE_P (mode)
    8006       131394 :             && icode != CODE_FOR_nothing
    8007              :             /* If the vec_duplicate target pattern does not specify an element
    8008              :                mode check that eltmode is the normal inner mode of the
    8009              :                requested vector mode.  But if the target allows eltmode
    8010              :                explicitly go ahead and use it.  */
    8011        90403 :             && (eltmode == GET_MODE_INNER (mode)
    8012            0 :                 || insn_data[icode].operand[1].mode == eltmode)
    8013        90403 :             && (elt = uniform_vector_p (exp))
    8014       152038 :             && !VECTOR_TYPE_P (TREE_TYPE (elt)))
    8015              :           {
    8016        17412 :             class expand_operand ops[2];
    8017        17412 :             create_output_operand (&ops[0], target, mode);
    8018        17412 :             create_input_operand (&ops[1], expand_normal (elt), eltmode);
    8019        17412 :             expand_insn (icode, 2, ops);
    8020        17412 :             if (!rtx_equal_p (target, ops[0].value))
    8021            0 :               emit_move_insn (target, ops[0].value);
    8022        17412 :             break;
    8023              :           }
    8024              :         /* Use sign-extension for uniform boolean vectors with
    8025              :            integer modes and single-bit mask entries.
    8026              :            Effectively "vec_duplicate" for bitmasks.  */
    8027       117214 :         if (elt_size == 1
    8028          146 :             && !TREE_SIDE_EFFECTS (exp)
    8029          146 :             && VECTOR_BOOLEAN_TYPE_P (type)
    8030          146 :             && SCALAR_INT_MODE_P (TYPE_MODE (type))
    8031          146 :             && (elt = uniform_vector_p (exp))
    8032          143 :             && !VECTOR_TYPE_P (TREE_TYPE (elt))
    8033       117214 :             && !BYTES_BIG_ENDIAN)
    8034              :           {
    8035          143 :             rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
    8036              :                                  expand_normal (elt));
    8037          143 :             rtx tmp = gen_reg_rtx (mode);
    8038          143 :             convert_move (tmp, op0, 0);
    8039              : 
    8040              :             /* Ensure no excess bits are set.
    8041              :                GCN needs this for nunits < 64.
    8042              :                x86 needs this for nunits < 8.  */
    8043          143 :             unsigned int nunits = TYPE_VECTOR_SUBPARTS (type).to_constant ();
    8044          143 :             if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
    8045            2 :               tmp = expand_binop (mode, and_optab, tmp,
    8046            2 :                                   GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
    8047              :                                   target, true, OPTAB_WIDEN);
    8048          143 :             if (tmp != target)
    8049          141 :               emit_move_insn (target, tmp);
    8050              :             break;
    8051              :           }
    8052              : 
    8053       117071 :         n_elts = TYPE_VECTOR_SUBPARTS (type);
    8054       117071 :         if (REG_P (target)
    8055       114143 :             && VECTOR_MODE_P (mode))
    8056              :           {
    8057       113982 :             const_n_elts = 0;
    8058       113982 :             if (CONSTRUCTOR_NELTS (exp)
    8059       113982 :                 && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
    8060              :                     == VECTOR_TYPE))
    8061              :               {
    8062         1308 :                 tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
    8063         1308 :                 gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
    8064              :                                       * TYPE_VECTOR_SUBPARTS (etype),
    8065              :                                       n_elts));
    8066              : 
    8067         3924 :                 icode = convert_optab_handler (vec_init_optab, mode,
    8068         1308 :                                                TYPE_MODE (etype));
    8069         1308 :                 const_n_elts = CONSTRUCTOR_NELTS (exp);
    8070         1308 :                 vec_vec_init_p = icode != CODE_FOR_nothing;
    8071              :               }
    8072       225348 :             else if (exact_div (n_elts, GET_MODE_NUNITS (eltmode))
    8073       112674 :                         .is_constant (&const_n_elts))
    8074              :               {
    8075              :                 /* For a non-const type vector, we check it is made up of
    8076              :                    similarly non-const type vectors. */
    8077       112674 :                 icode = convert_optab_handler (vec_init_optab, mode, eltmode);
    8078              :               }
    8079              : 
    8080       113982 :           if (const_n_elts && icode != CODE_FOR_nothing)
    8081              :             {
    8082       113340 :               vector = rtvec_alloc (const_n_elts);
    8083       422482 :               for (unsigned int k = 0; k < const_n_elts; k++)
    8084       309142 :                 RTVEC_ELT (vector, k) = CONST0_RTX (eltmode);
    8085              :             }
    8086              :           }
    8087              : 
    8088              :         /* Compute the size of the elements in the CTOR.  It differs
    8089              :            from the size of the vector type elements only when the
    8090              :            CTOR elements are vectors themselves.  */
    8091       117071 :         tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
    8092       117071 :                          ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
    8093       117071 :                          : elttype);
    8094       117071 :         if (VECTOR_TYPE_P (val_type))
    8095         1626 :           bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
    8096              :         else
    8097       115445 :           bitsize = elt_size;
    8098              : 
    8099              :         /* If the constructor has fewer elements than the vector,
    8100              :            clear the whole array first.  Similarly if this is static
    8101              :            constructor of a non-BLKmode object.  */
    8102       117071 :         if (cleared)
    8103              :           need_to_clear = false;
    8104       117071 :         else if (REG_P (target) && TREE_STATIC (exp))
    8105              :           need_to_clear = true;
    8106              :         else
    8107              :           {
    8108              :             poly_uint64 count = 0, zero_count = 0;
    8109              :             tree value;
    8110              : 
    8111       464920 :             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
    8112              :               {
    8113       347849 :                 poly_int64 n_elts_here = exact_div (bitsize, elt_size);
    8114       347849 :                 count += n_elts_here;
    8115       347849 :                 if (mostly_zeros_p (value))
    8116       347849 :                   zero_count += n_elts_here;
    8117              :               }
    8118              : 
    8119              :             /* Clear the entire vector first if there are any missing elements,
    8120              :                or if the incidence of zero elements is >= 75%.  */
    8121       117071 :             need_to_clear = (maybe_lt (count, n_elts)
    8122       117071 :                              || maybe_gt (4 * zero_count, 3 * count));
    8123              :           }
    8124              : 
    8125         1057 :         if (need_to_clear && maybe_gt (size, 0) && !vector)
    8126              :           {
    8127          686 :             if (REG_P (target))
    8128            1 :               emit_move_insn (target, CONST0_RTX (mode));
    8129              :             else
    8130          685 :               clear_storage (target, gen_int_mode (size, Pmode),
    8131              :                              BLOCK_OP_NORMAL);
    8132              :             cleared = 1;
    8133              :           }
    8134              : 
    8135              :         /* Inform later passes that the old value is dead.  */
    8136       117071 :         if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
    8137              :           {
    8138          484 :             emit_move_insn (target, CONST0_RTX (mode));
    8139          484 :             cleared = 1;
    8140              :           }
    8141              : 
    8142       117071 :         if (MEM_P (target))
    8143         2928 :           alias = MEM_ALIAS_SET (target);
    8144              :         else
    8145       114143 :           alias = get_alias_set (elttype);
    8146              : 
    8147              :         /* Store each element of the constructor into the corresponding
    8148              :            element of TARGET, determined by counting the elements.  */
    8149       117071 :         HOST_WIDE_INT chunk_size = 0;
    8150       117071 :         bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
    8151              :                                                      &chunk_size);
    8152       117071 :         gcc_assert (chunk_multiple_p || vec_vec_init_p);
    8153              : 
    8154       464920 :         for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
    8155              :              idx++)
    8156              :           {
    8157       347849 :             HOST_WIDE_INT eltpos;
    8158       347849 :             tree value = ce->value;
    8159              : 
    8160       347849 :             if (cleared && initializer_zerop (value))
    8161         7597 :               continue;
    8162              : 
    8163       340252 :             if (ce->index)
    8164        44577 :               eltpos = tree_to_uhwi (ce->index);
    8165              :             else
    8166       295675 :               eltpos = idx * chunk_size;
    8167              : 
    8168       340252 :             if (vector)
    8169              :               {
    8170       308174 :                 if (vec_vec_init_p)
    8171              :                   {
    8172         2600 :                     gcc_assert (ce->index == NULL_TREE);
    8173         2600 :                     gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
    8174         2600 :                     eltpos = idx;
    8175              :                   }
    8176              :                 else
    8177       305574 :                   gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
    8178       308174 :                 RTVEC_ELT (vector, eltpos) = expand_normal (value);
    8179              :               }
    8180              :             else
    8181              :               {
    8182        32078 :                 machine_mode value_mode
    8183        32078 :                   = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
    8184        32078 :                      ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
    8185        32078 :                 bitpos = eltpos * elt_size;
    8186        32078 :                 store_constructor_field (target, bitsize, bitpos, 0,
    8187        32078 :                                          bitregion_end, value_mode,
    8188              :                                          value, cleared, alias, reverse);
    8189              :               }
    8190              :           }
    8191              : 
    8192       117071 :         if (vector)
    8193       113340 :           emit_insn (GEN_FCN (icode) (target,
    8194              :                                       gen_rtx_PARALLEL (mode, vector)));
    8195              :         break;
    8196              :       }
    8197              : 
    8198            0 :     default:
    8199            0 :       gcc_unreachable ();
    8200              :     }
    8201       239825 : }
    8202              : 
    8203              : /* Store the value of EXP (an expression tree)
    8204              :    into a subfield of TARGET which has mode MODE and occupies
    8205              :    BITSIZE bits, starting BITPOS bits from the start of TARGET.
    8206              :    If MODE is VOIDmode, it means that we are storing into a bit-field.
    8207              : 
    8208              :    BITREGION_START is bitpos of the first bitfield in this region.
    8209              :    BITREGION_END is the bitpos of the ending bitfield in this region.
    8210              :    These two fields are 0, if the C++ memory model does not apply,
    8211              :    or we are not interested in keeping track of bitfield regions.
    8212              : 
    8213              :    Always return const0_rtx unless we have something particular to
    8214              :    return.
    8215              : 
    8216              :    ALIAS_SET is the alias set for the destination.  This value will
    8217              :    (in general) be different from that for TARGET, since TARGET is a
    8218              :    reference to the containing structure.
    8219              : 
    8220              :    If NONTEMPORAL is true, try generating a nontemporal store.
    8221              : 
    8222              :    If REVERSE is true, the store is to be done in reverse order.  */
    8223              : 
    8224              : static rtx
    8225      4685450 : store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
    8226              :              poly_uint64 bitregion_start, poly_uint64 bitregion_end,
    8227              :              machine_mode mode, tree exp,
    8228              :              alias_set_type alias_set, bool nontemporal,  bool reverse)
    8229              : {
    8230      4685450 :   if (TREE_CODE (exp) == ERROR_MARK)
    8231            0 :     return const0_rtx;
    8232              : 
    8233              :   /* If we have nothing to store, do nothing unless the expression has
    8234              :      side-effects.  Don't do that for zero sized addressable lhs of
    8235              :      calls.  */
    8236      4685450 :   if (known_eq (bitsize, 0)
    8237      4685450 :       && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
    8238            3 :           || TREE_CODE (exp) != CALL_EXPR))
    8239            0 :     return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
    8240              : 
    8241      4685450 :   if (GET_CODE (target) == CONCAT)
    8242              :     {
    8243              :       /* We're storing into a struct containing a single __complex.  */
    8244              : 
    8245            0 :       gcc_assert (known_eq (bitpos, 0));
    8246            0 :       return store_expr (exp, target, 0, nontemporal, reverse);
    8247              :     }
    8248              : 
    8249              :   /* If the structure is in a register or if the component
    8250              :      is a bit field, we cannot use addressing to access it.
    8251              :      Use bit-field techniques or SUBREG to store in it.  */
    8252              : 
    8253      4685450 :   poly_int64 decl_bitsize;
    8254      4685450 :   if (mode == VOIDmode
    8255      4617906 :       || (mode != BLKmode && ! direct_store[(int) mode]
    8256         5326 :           && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
    8257         5324 :           && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
    8258      4612611 :       || REG_P (target)
    8259      3946675 :       || GET_CODE (target) == SUBREG
    8260              :       /* If the field isn't aligned enough to store as an ordinary memref,
    8261              :          store it as a bit field.  */
    8262      3946675 :       || (mode != BLKmode
    8263      3833510 :           && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
    8264      7578594 :                 || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
    8265        46973 :                && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
    8266      3833510 :               || !multiple_p (bitpos, BITS_PER_UNIT)))
    8267      3946675 :       || (known_size_p (bitsize)
    8268      3946663 :           && mode != BLKmode
    8269      3833510 :           && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
    8270              :       /* If the RHS and field are a constant size and the size of the
    8271              :          RHS isn't the same size as the bitfield, we must use bitfield
    8272              :          operations.  */
    8273      3946666 :       || (known_size_p (bitsize)
    8274      3946654 :           && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
    8275      3946654 :           && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
    8276              :                        bitsize)
    8277              :           /* Except for initialization of full bytes from a CONSTRUCTOR, which
    8278              :              we will handle specially below.  */
    8279           34 :           && !(TREE_CODE (exp) == CONSTRUCTOR
    8280           11 :                && multiple_p (bitsize, BITS_PER_UNIT))
    8281              :           /* And except for bitwise copying of TREE_ADDRESSABLE types,
    8282              :              where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
    8283              :              includes some extra padding.  store_expr / expand_expr will in
    8284              :              that case call get_inner_reference that will have the bitsize
    8285              :              we check here and thus the block move will not clobber the
    8286              :              padding that shouldn't be clobbered.  In the future we could
    8287              :              replace the TREE_ADDRESSABLE check with a check that
    8288              :              get_base_address needs to live in memory.  */
    8289           23 :           && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
    8290            9 :               || TREE_CODE (exp) != COMPONENT_REF
    8291            6 :               || !multiple_p (bitsize, BITS_PER_UNIT)
    8292            6 :               || !multiple_p (bitpos, BITS_PER_UNIT)
    8293            6 :               || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
    8294              :                                    &decl_bitsize)
    8295            6 :               || maybe_ne (decl_bitsize, bitsize))
    8296              :           /* A call with an addressable return type and return-slot
    8297              :              optimization must not need bitfield operations but we must
    8298              :              pass down the original target.  */
    8299           17 :           && (TREE_CODE (exp) != CALL_EXPR
    8300            6 :               || !TREE_ADDRESSABLE (TREE_TYPE (exp))
    8301            0 :               || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
    8302              :       /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
    8303              :          decl we must use bitfield operations.  */
    8304      8632099 :       || (known_size_p (bitsize)
    8305      3946637 :           && TREE_CODE (exp) == MEM_REF
    8306        30187 :           && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
    8307        24010 :           && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    8308        19652 :           && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    8309         5340 :           && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
    8310              :     {
    8311       739038 :       rtx temp;
    8312       739038 :       gimple *nop_def;
    8313              : 
    8314              :       /* If EXP is a NOP_EXPR of precision less than its mode, then that
    8315              :          implies a mask operation.  If the precision is the same size as
    8316              :          the field we're storing into, that mask is redundant.  This is
    8317              :          particularly common with bit field assignments generated by the
    8318              :          C front end.  */
    8319       739038 :       nop_def = get_def_for_expr (exp, NOP_EXPR);
    8320       739038 :       if (nop_def)
    8321              :         {
    8322         5927 :           tree type = TREE_TYPE (exp);
    8323         5927 :           if (INTEGRAL_TYPE_P (type)
    8324         5734 :               && maybe_ne (TYPE_PRECISION (type),
    8325        11468 :                            GET_MODE_BITSIZE (TYPE_MODE (type)))
    8326         9317 :               && known_eq (bitsize, TYPE_PRECISION (type)))
    8327              :             {
    8328         3285 :               tree op = gimple_assign_rhs1 (nop_def);
    8329         3285 :               type = TREE_TYPE (op);
    8330         3285 :               if (INTEGRAL_TYPE_P (type)
    8331         3285 :                   && known_ge (TYPE_PRECISION (type), bitsize))
    8332              :                 exp = op;
    8333              :             }
    8334              :         }
    8335              : 
    8336       739038 :       temp = expand_normal (exp);
    8337              : 
    8338              :       /* We don't support variable-sized BLKmode bitfields, since our
    8339              :          handling of BLKmode is bound up with the ability to break
    8340              :          things into words.  */
    8341       739038 :       gcc_assert (mode != BLKmode || bitsize.is_constant ());
    8342              : 
    8343              :       /* Handle calls that return values in multiple non-contiguous locations.
    8344              :          The Irix 6 ABI has examples of this.  */
    8345       739038 :       if (GET_CODE (temp) == PARALLEL)
    8346              :         {
    8347            6 :           HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
    8348            6 :           machine_mode temp_mode = GET_MODE (temp);
    8349            6 :           if (temp_mode == BLKmode || temp_mode == VOIDmode)
    8350            6 :             temp_mode
    8351            6 :               = smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
    8352            6 :           rtx temp_target = gen_reg_rtx (temp_mode);
    8353            6 :           emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
    8354            6 :           temp = temp_target;
    8355              :         }
    8356              : 
    8357              :       /* Handle calls that return BLKmode values in registers.  */
    8358       739032 :       else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
    8359              :         {
    8360            0 :           rtx temp_target = gen_reg_rtx (GET_MODE (temp));
    8361            0 :           copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
    8362            0 :           temp = temp_target;
    8363              :         }
    8364              : 
    8365              :       /* If the value has aggregate type and an integral mode then, if BITSIZE
    8366              :          is narrower than this mode and this is for big-endian data, we first
    8367              :          need to put the value into the low-order bits for store_bit_field,
    8368              :          except when MODE is BLKmode and BITSIZE larger than the word size
    8369              :          (see the handling of fields larger than a word in store_bit_field).
    8370              :          Moreover, the field may be not aligned on a byte boundary; in this
    8371              :          case, if it has reverse storage order, it needs to be accessed as a
    8372              :          scalar field with reverse storage order and we must first put the
    8373              :          value into target order.  */
    8374       739038 :       scalar_int_mode temp_mode;
    8375      1476056 :       if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
    8376       739788 :           && is_int_mode (GET_MODE (temp), &temp_mode))
    8377              :         {
    8378         2472 :           HOST_WIDE_INT size = GET_MODE_BITSIZE (temp_mode);
    8379              : 
    8380         2472 :           reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
    8381              : 
    8382         2472 :           if (reverse)
    8383            0 :             temp = flip_storage_order (temp_mode, temp);
    8384              : 
    8385         2472 :           gcc_checking_assert (known_le (bitsize, size));
    8386         2472 :           if (maybe_lt (bitsize, size)
    8387         2472 :               && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
    8388              :               /* Use of to_constant for BLKmode was checked above.  */
    8389              :               && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
    8390            0 :             temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
    8391              :                                  size - bitsize, NULL_RTX, 1);
    8392              :         }
    8393              : 
    8394              :       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE.  */
    8395       671494 :       if (mode != VOIDmode && mode != BLKmode
    8396      1410244 :           && mode != TYPE_MODE (TREE_TYPE (exp)))
    8397            4 :         temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
    8398              : 
    8399              :       /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
    8400              :          and BITPOS must be aligned on a byte boundary.  If so, we simply do
    8401              :          a block copy.  Likewise for a BLKmode-like TARGET.  */
    8402       739038 :       if (GET_MODE (temp) == BLKmode
    8403       739038 :           && (GET_MODE (target) == BLKmode
    8404          196 :               || (MEM_P (target)
    8405            0 :                   && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
    8406            0 :                   && multiple_p (bitpos, BITS_PER_UNIT)
    8407            0 :                   && multiple_p (bitsize, BITS_PER_UNIT))))
    8408              :         {
    8409           86 :           gcc_assert (MEM_P (target) && MEM_P (temp));
    8410           86 :           poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
    8411           86 :           poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
    8412              : 
    8413           86 :           target = adjust_address (target, VOIDmode, bytepos);
    8414           86 :           emit_block_move (target, temp,
    8415           86 :                            gen_int_mode (bytesize, Pmode),
    8416              :                            BLOCK_OP_NORMAL);
    8417              : 
    8418           86 :           return const0_rtx;
    8419              :         }
    8420              : 
    8421              :       /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
    8422              :          word size, we need to load the value (see again store_bit_field).  */
    8423       738970 :       if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
    8424              :         {
    8425           76 :           temp_mode = smallest_int_mode_for_size (bitsize).require ();
    8426           76 :           temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
    8427              :                                     temp_mode, false, NULL);
    8428              :         }
    8429              : 
    8430              :       /* Store the value in the bitfield.  */
    8431       738952 :       gcc_checking_assert (known_ge (bitpos, 0));
    8432       738952 :       store_bit_field (target, bitsize, bitpos,
    8433              :                        bitregion_start, bitregion_end,
    8434              :                        mode, temp, reverse, false);
    8435              : 
    8436       738952 :       return const0_rtx;
    8437              :     }
    8438              :   else
    8439              :     {
    8440              :       /* Now build a reference to just the desired component.  */
    8441      3946412 :       rtx to_rtx = adjust_address (target, mode,
    8442              :                                    exact_div (bitpos, BITS_PER_UNIT));
    8443              : 
    8444      3946412 :       if (to_rtx == target)
    8445      1264521 :         to_rtx = copy_rtx (to_rtx);
    8446              : 
    8447      7621783 :       if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
    8448      3422538 :         set_mem_alias_set (to_rtx, alias_set);
    8449              : 
    8450              :       /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
    8451              :          into a target smaller than its type; handle that case now.  */
    8452      3946412 :       if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (bitsize))
    8453              :         {
    8454        67806 :           poly_int64 bytesize = exact_div (bitsize, BITS_PER_UNIT);
    8455        67806 :           store_constructor (exp, to_rtx, 0, bytesize, reverse);
    8456        67806 :           return to_rtx;
    8457              :         }
    8458              : 
    8459      3878606 :       return store_expr (exp, to_rtx, 0, nontemporal, reverse);
    8460              :     }
    8461              : }
    8462              : 
    8463              : /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
    8464              :    an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
    8465              :    codes and find the ultimate containing object, which we return.
    8466              : 
    8467              :    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
    8468              :    bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
    8469              :    storage order of the field.
    8470              :    If the position of the field is variable, we store a tree
    8471              :    giving the variable offset (in units) in *POFFSET.
    8472              :    This offset is in addition to the bit position.
    8473              :    If the position is not variable, we store 0 in *POFFSET.
    8474              : 
    8475              :    If any of the extraction expressions is volatile,
    8476              :    we store 1 in *PVOLATILEP.  Otherwise we don't change that.
    8477              : 
    8478              :    If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
    8479              :    Otherwise, it is a mode that can be used to access the field.
    8480              : 
    8481              :    If the field describes a variable-sized object, *PMODE is set to
    8482              :    BLKmode and *PBITSIZE is set to -1.  An access cannot be made in
    8483              :    this case, but the address of the object can be found.  */
    8484              : 
    8485              : tree
    8486    271636889 : get_inner_reference (tree exp, poly_int64 *pbitsize,
    8487              :                      poly_int64 *pbitpos, tree *poffset,
    8488              :                      machine_mode *pmode, int *punsignedp,
    8489              :                      int *preversep, int *pvolatilep)
    8490              : {
    8491    271636889 :   tree size_tree = 0;
    8492    271636889 :   machine_mode mode = VOIDmode;
    8493    271636889 :   bool blkmode_bitfield = false;
    8494    271636889 :   tree offset = size_zero_node;
    8495    271636889 :   poly_offset_int bit_offset = 0;
    8496              : 
    8497              :   /* First get the mode, signedness, storage order and size.  We do this from
    8498              :      just the outermost expression.  */
    8499    271636889 :   *pbitsize = -1;
    8500    271636889 :   if (TREE_CODE (exp) == COMPONENT_REF)
    8501              :     {
    8502    128604552 :       tree field = TREE_OPERAND (exp, 1);
    8503    128604552 :       size_tree = DECL_SIZE (field);
    8504    128604552 :       if (flag_strict_volatile_bitfields > 0
    8505           58 :           && TREE_THIS_VOLATILE (exp)
    8506           40 :           && DECL_BIT_FIELD_TYPE (field)
    8507    128604574 :           && DECL_MODE (field) != BLKmode)
    8508              :         /* Volatile bitfields should be accessed in the mode of the
    8509              :              field's type, not the mode computed based on the bit
    8510              :              size.  */
    8511           22 :         mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
    8512    128604530 :       else if (!DECL_BIT_FIELD (field))
    8513              :         {
    8514    125248829 :           mode = DECL_MODE (field);
    8515              :           /* For vector fields re-check the target flags, as DECL_MODE
    8516              :              could have been set with different target flags than
    8517              :              the current function has.  */
    8518    125248829 :           if (VECTOR_TYPE_P (TREE_TYPE (field))
    8519    125248829 :               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
    8520       319998 :             mode = TYPE_MODE (TREE_TYPE (field));
    8521              :         }
    8522      3355701 :       else if (DECL_MODE (field) == BLKmode)
    8523          620 :         blkmode_bitfield = true;
    8524              : 
    8525    128604552 :       *punsignedp = DECL_UNSIGNED (field);
    8526              :     }
    8527    143032337 :   else if (TREE_CODE (exp) == BIT_FIELD_REF)
    8528              :     {
    8529       582956 :       size_tree = TREE_OPERAND (exp, 1);
    8530      1165493 :       *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
    8531      1022383 :                      || TYPE_UNSIGNED (TREE_TYPE (exp)));
    8532              : 
    8533              :       /* For vector element types with the correct size of access or for
    8534              :          vector typed accesses use the mode of the access type.  */
    8535       582956 :       if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
    8536       429436 :            && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
    8537       391170 :            && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
    8538       621257 :           || VECTOR_TYPE_P (TREE_TYPE (exp)))
    8539       412953 :         mode = TYPE_MODE (TREE_TYPE (exp));
    8540              :     }
    8541              :   else
    8542              :     {
    8543    142449381 :       mode = TYPE_MODE (TREE_TYPE (exp));
    8544    142449381 :       *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
    8545              : 
    8546    142449381 :       if (mode == BLKmode)
    8547     57318043 :         size_tree = TYPE_SIZE (TREE_TYPE (exp));
    8548              :       else
    8549    170262676 :         *pbitsize = GET_MODE_BITSIZE (mode);
    8550              :     }
    8551              : 
    8552    271636889 :   if (size_tree != 0)
    8553              :     {
    8554    185805489 :       if (!poly_int_tree_p (size_tree, pbitsize))
    8555       365787 :         mode = BLKmode, *pbitsize = -1;
    8556              :     }
    8557              : 
    8558    271636889 :   *preversep = reverse_storage_order_for_component_p (exp);
    8559              : 
    8560              :   /* Compute cumulative bit-offset for nested component-refs and array-refs,
    8561              :      and find the ultimate containing object.  */
    8562    716946105 :   while (1)
    8563              :     {
    8564    494291497 :       switch (TREE_CODE (exp))
    8565              :         {
    8566       582956 :         case BIT_FIELD_REF:
    8567       582956 :           bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
    8568       582956 :           break;
    8569              : 
    8570    188430709 :         case COMPONENT_REF:
    8571    188430709 :           {
    8572    188430709 :             tree field = TREE_OPERAND (exp, 1);
    8573    188430709 :             tree this_offset = component_ref_field_offset (exp);
    8574              : 
    8575              :             /* If this field hasn't been filled in yet, don't go past it.
    8576              :                This should only happen when folding expressions made during
    8577              :                type construction.  */
    8578    188430709 :             if (this_offset == 0)
    8579              :               break;
    8580              : 
    8581    188430709 :             offset = size_binop (PLUS_EXPR, offset, this_offset);
    8582    188430709 :             bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
    8583              : 
    8584              :             /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN.  */
    8585              :           }
    8586    188430709 :           break;
    8587              : 
    8588     29614703 :         case ARRAY_REF:
    8589     29614703 :         case ARRAY_RANGE_REF:
    8590     29614703 :           {
    8591     29614703 :             tree index = TREE_OPERAND (exp, 1);
    8592     29614703 :             tree low_bound = array_ref_low_bound (exp);
    8593     29614703 :             tree unit_size = array_ref_element_size (exp);
    8594              : 
    8595              :             /* We assume all arrays have sizes that are a multiple of a byte.
    8596              :                First subtract the lower bound, if any, in the type of the
    8597              :                index, then convert to sizetype and multiply by the size of
    8598              :                the array element.  */
    8599     29614703 :             if (! integer_zerop (low_bound))
    8600       805959 :               index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
    8601              :                                    index, low_bound);
    8602              : 
    8603     29614703 :             offset = size_binop (PLUS_EXPR, offset,
    8604              :                                  size_binop (MULT_EXPR,
    8605              :                                              fold_convert (sizetype, index),
    8606              :                                              unit_size));
    8607              :           }
    8608     29614703 :           break;
    8609              : 
    8610              :         case REALPART_EXPR:
    8611              :           break;
    8612              : 
    8613              :         case IMAGPART_EXPR:
    8614    222654608 :           bit_offset += *pbitsize;
    8615              :           break;
    8616              : 
    8617              :         case VIEW_CONVERT_EXPR:
    8618              :           break;
    8619              : 
    8620     87466870 :         case MEM_REF:
    8621              :           /* Hand back the decl for MEM[&decl, off].  */
    8622     87466870 :           if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
    8623              :             {
    8624     19167585 :               tree off = TREE_OPERAND (exp, 1);
    8625     19167585 :               if (!integer_zerop (off))
    8626              :                 {
    8627     10591450 :                   poly_offset_int boff = mem_ref_offset (exp);
    8628     10591450 :                   boff <<= LOG2_BITS_PER_UNIT;
    8629     10591450 :                   bit_offset += boff;
    8630              :                 }
    8631     19167585 :               exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    8632              :             }
    8633     87466870 :           goto done;
    8634              : 
    8635    184170019 :         default:
    8636    184170019 :           goto done;
    8637              :         }
    8638              : 
    8639              :       /* If any reference in the chain is volatile, the effect is volatile.  */
    8640    222654608 :       if (TREE_THIS_VOLATILE (exp))
    8641       549236 :         *pvolatilep = 1;
    8642              : 
    8643    222654608 :       exp = TREE_OPERAND (exp, 0);
    8644    222654608 :     }
    8645    271636889 :  done:
    8646              : 
    8647              :   /* If OFFSET is constant, see if we can return the whole thing as a
    8648              :      constant bit position.  Make sure to handle overflow during
    8649              :      this conversion.  */
    8650    271636889 :   if (poly_int_tree_p (offset))
    8651              :     {
    8652    257982892 :       poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
    8653    257982892 :                                       TYPE_PRECISION (sizetype));
    8654    257982892 :       tem <<= LOG2_BITS_PER_UNIT;
    8655    257982892 :       tem += bit_offset;
    8656    257982892 :       if (tem.to_shwi (pbitpos))
    8657    257981490 :         *poffset = offset = NULL_TREE;
    8658              :     }
    8659              : 
    8660              :   /* Otherwise, split it up.  */
    8661    257982892 :   if (offset)
    8662              :     {
    8663              :       /* Avoid returning a negative bitpos as this may wreak havoc later.  */
    8664     13655399 :       if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
    8665              :         {
    8666          283 :           *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
    8667          283 :           poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
    8668          283 :           offset = size_binop (PLUS_EXPR, offset,
    8669              :                                build_int_cst (sizetype, bytes.force_shwi ()));
    8670              :         }
    8671              : 
    8672     13655399 :       *poffset = offset;
    8673              :     }
    8674              : 
    8675              :   /* We can use BLKmode for a byte-aligned BLKmode bitfield.  */
    8676    271636889 :   if (mode == VOIDmode
    8677      5197100 :       && blkmode_bitfield
    8678          620 :       && multiple_p (*pbitpos, BITS_PER_UNIT)
    8679    271637377 :       && multiple_p (*pbitsize, BITS_PER_UNIT))
    8680            5 :     *pmode = BLKmode;
    8681              :   else
    8682    271636884 :     *pmode = mode;
    8683              : 
    8684    271636889 :   return exp;
    8685              : }
    8686              : 
    8687              : /* Alignment in bits the TARGET of an assignment may be assumed to have.  */
    8688              : 
    8689              : static unsigned HOST_WIDE_INT
    8690       508484 : target_align (const_tree target)
    8691              : {
    8692              :   /* We might have a chain of nested references with intermediate misaligning
    8693              :      bitfields components, so need to recurse to find out.  */
    8694              : 
    8695       508484 :   unsigned HOST_WIDE_INT this_align, outer_align;
    8696              : 
    8697       508484 :   switch (TREE_CODE (target))
    8698              :     {
    8699              :     case BIT_FIELD_REF:
    8700              :       return 1;
    8701              : 
    8702       139781 :     case COMPONENT_REF:
    8703       139781 :       this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
    8704       139781 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8705       139781 :       return MIN (this_align, outer_align);
    8706              : 
    8707       187857 :     case ARRAY_REF:
    8708       187857 :     case ARRAY_RANGE_REF:
    8709       187857 :       this_align = TYPE_ALIGN (TREE_TYPE (target));
    8710       187857 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8711       187857 :       return MIN (this_align, outer_align);
    8712              : 
    8713         4338 :     CASE_CONVERT:
    8714         4338 :     case NON_LVALUE_EXPR:
    8715         4338 :     case VIEW_CONVERT_EXPR:
    8716         4338 :       this_align = TYPE_ALIGN (TREE_TYPE (target));
    8717         4338 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8718         4338 :       return MAX (this_align, outer_align);
    8719              : 
    8720       176503 :     default:
    8721       176503 :       return TYPE_ALIGN (TREE_TYPE (target));
    8722              :     }
    8723              : }
    8724              : 
    8725              : 
    8726              : /* Given an rtx VALUE that may contain additions and multiplications, return
    8727              :    an equivalent value that just refers to a register, memory, or constant.
    8728              :    This is done by generating instructions to perform the arithmetic and
    8729              :    returning a pseudo-register containing the value.
    8730              : 
    8731              :    The returned value may be a REG, SUBREG, MEM or constant.  */
    8732              : 
    8733              : rtx
    8734     30640564 : force_operand (rtx value, rtx target)
    8735              : {
    8736     30640564 :   rtx op1, op2;
    8737              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
    8738     30640564 :   rtx subtarget = get_subtarget (target);
    8739     30640564 :   enum rtx_code code = GET_CODE (value);
    8740              : 
    8741              :   /* Check for subreg applied to an expression produced by loop optimizer.  */
    8742     30640564 :   if (code == SUBREG
    8743       244009 :       && !REG_P (SUBREG_REG (value))
    8744          189 :       && !MEM_P (SUBREG_REG (value)))
    8745              :     {
    8746          189 :       value
    8747          189 :         = simplify_gen_subreg (GET_MODE (value),
    8748          189 :                                force_reg (GET_MODE (SUBREG_REG (value)),
    8749              :                                           force_operand (SUBREG_REG (value),
    8750              :                                                          NULL_RTX)),
    8751          189 :                                GET_MODE (SUBREG_REG (value)),
    8752          189 :                                SUBREG_BYTE (value));
    8753          189 :       code = GET_CODE (value);
    8754              :     }
    8755              : 
    8756              :   /* Check for a PIC address load.  */
    8757     30640564 :   if ((code == PLUS || code == MINUS)
    8758      3643220 :       && XEXP (value, 0) == pic_offset_table_rtx
    8759         1949 :       && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
    8760         1949 :           || GET_CODE (XEXP (value, 1)) == LABEL_REF
    8761         1949 :           || GET_CODE (XEXP (value, 1)) == CONST))
    8762              :     {
    8763          202 :       if (!subtarget)
    8764          202 :         subtarget = gen_reg_rtx (GET_MODE (value));
    8765          202 :       emit_move_insn (subtarget, value);
    8766          202 :       return subtarget;
    8767              :     }
    8768              : 
    8769     30640362 :   if (ARITHMETIC_P (value))
    8770              :     {
    8771      3758336 :       op2 = XEXP (value, 1);
    8772      3758336 :       if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
    8773      3758336 :         subtarget = 0;
    8774      3758336 :       if (code == MINUS && CONST_INT_P (op2))
    8775              :         {
    8776            0 :           code = PLUS;
    8777            0 :           op2 = negate_rtx (GET_MODE (value), op2);
    8778              :         }
    8779              : 
    8780              :       /* Check for an addition with OP2 a constant integer and our first
    8781              :          operand a PLUS of a virtual register and something else.  In that
    8782              :          case, we want to emit the sum of the virtual register and the
    8783              :          constant first and then add the other value.  This allows virtual
    8784              :          register instantiation to simply modify the constant rather than
    8785              :          creating another one around this addition.  */
    8786      3584170 :       if (code == PLUS && CONST_INT_P (op2)
    8787      3201381 :           && GET_CODE (XEXP (value, 0)) == PLUS
    8788       113308 :           && REG_P (XEXP (XEXP (value, 0), 0))
    8789      3814700 :           && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
    8790              :         {
    8791         1769 :           rtx temp = expand_simple_binop (GET_MODE (value), code,
    8792              :                                           XEXP (XEXP (value, 0), 0), op2,
    8793              :                                           subtarget, 0, OPTAB_LIB_WIDEN);
    8794         1769 :           return expand_simple_binop (GET_MODE (value), code, temp,
    8795         1769 :                                       force_operand (XEXP (XEXP (value,
    8796              :                                                                  0), 1), 0),
    8797         1769 :                                       target, 0, OPTAB_LIB_WIDEN);
    8798              :         }
    8799              : 
    8800      3756567 :       op1 = force_operand (XEXP (value, 0), subtarget);
    8801      3756567 :       op2 = force_operand (op2, NULL_RTX);
    8802      3756567 :       switch (code)
    8803              :         {
    8804        97266 :         case MULT:
    8805        97266 :           return expand_mult (GET_MODE (value), op1, op2, target, 1);
    8806          222 :         case DIV:
    8807          222 :           if (!INTEGRAL_MODE_P (GET_MODE (value)))
    8808          222 :             return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8809          222 :                                         target, 1, OPTAB_LIB_WIDEN);
    8810              :           else
    8811            0 :             return expand_divmod (0,
    8812              :                                   FLOAT_MODE_P (GET_MODE (value))
    8813              :                                   ? RDIV_EXPR : TRUNC_DIV_EXPR,
    8814            0 :                                   GET_MODE (value), op1, op2, target, 0);
    8815            0 :         case MOD:
    8816            0 :           return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
    8817            0 :                                 target, 0);
    8818          316 :         case UDIV:
    8819          316 :           return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
    8820          316 :                                 target, 1);
    8821            0 :         case UMOD:
    8822            0 :           return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
    8823            0 :                                 target, 1);
    8824           84 :         case ASHIFTRT:
    8825           84 :           return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8826           84 :                                       target, 0, OPTAB_LIB_WIDEN);
    8827      3658679 :         default:
    8828      3658679 :           return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8829      3658679 :                                       target, 1, OPTAB_LIB_WIDEN);
    8830              :         }
    8831              :     }
    8832     26882026 :   if (UNARY_P (value))
    8833              :     {
    8834        15479 :       if (!target)
    8835         6854 :         target = gen_reg_rtx (GET_MODE (value));
    8836              :       /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
    8837              :          while FIX with floating point mode rounds toward zero.  So, some
    8838              :          targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
    8839              :          to express rounding toward zero during the conversion to int.
    8840              :          expand_fix isn't able to handle that, it can only handle
    8841              :          FIX/UNSIGNED_FIX from floating point mode to integral one.  */
    8842        15479 :       if ((code == FIX || code == UNSIGNED_FIX)
    8843            4 :           && GET_CODE (XEXP (value, 0)) == FIX
    8844            0 :           && (GET_MODE (XEXP (value, 0))
    8845            0 :               == GET_MODE (XEXP (XEXP (value, 0), 0))))
    8846            0 :         op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
    8847              :       else
    8848        15479 :         op1 = force_operand (XEXP (value, 0), NULL_RTX);
    8849        15479 :       switch (code)
    8850              :         {
    8851         4627 :         case ZERO_EXTEND:
    8852         4627 :         case SIGN_EXTEND:
    8853         4627 :         case TRUNCATE:
    8854         4627 :         case FLOAT_EXTEND:
    8855         4627 :         case FLOAT_TRUNCATE:
    8856         4627 :           convert_move (target, op1, code == ZERO_EXTEND);
    8857         4627 :           return target;
    8858              : 
    8859            4 :         case FIX:
    8860            4 :         case UNSIGNED_FIX:
    8861            4 :           expand_fix (target, op1, code == UNSIGNED_FIX);
    8862            4 :           return target;
    8863              : 
    8864          120 :         case FLOAT:
    8865          120 :         case UNSIGNED_FLOAT:
    8866          120 :           expand_float (target, op1, code == UNSIGNED_FLOAT);
    8867          120 :           return target;
    8868              : 
    8869        10728 :         default:
    8870        10728 :           return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
    8871              :         }
    8872              :     }
    8873              : 
    8874              : #ifdef INSN_SCHEDULING
    8875              :   /* On machines that have insn scheduling, we want all memory reference to be
    8876              :      explicit, so we need to deal with such paradoxical SUBREGs.  */
    8877     26866547 :   if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
    8878            0 :     value
    8879            0 :       = simplify_gen_subreg (GET_MODE (value),
    8880            0 :                              force_reg (GET_MODE (SUBREG_REG (value)),
    8881              :                                         force_operand (SUBREG_REG (value),
    8882              :                                                        NULL_RTX)),
    8883              :                              GET_MODE (SUBREG_REG (value)),
    8884            0 :                              SUBREG_BYTE (value));
    8885              : #endif
    8886              : 
    8887              :   return value;
    8888              : }
    8889              : 
    8890              : /* Subroutine of expand_expr: return true iff there is no way that
    8891              :    EXP can reference X, which is being modified.  TOP_P is nonzero if this
    8892              :    call is going to be used to determine whether we need a temporary
    8893              :    for EXP, as opposed to a recursive call to this function.
    8894              : 
    8895              :    It is always safe for this routine to return false since it merely
    8896              :    searches for optimization opportunities.  */
    8897              : 
    8898              : bool
    8899      8633202 : safe_from_p (const_rtx x, tree exp, int top_p)
    8900              : {
    8901      8633218 :   rtx exp_rtl = 0;
    8902      8633218 :   int i, nops;
    8903              : 
    8904      8633218 :   if (x == 0
    8905              :       /* If EXP has varying size, we MUST use a target since we currently
    8906              :          have no way of allocating temporaries of variable size
    8907              :          (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
    8908              :          So we assume here that something at a higher level has prevented a
    8909              :          clash.  This is somewhat bogus, but the best we can do.  Only
    8910              :          do this when X is BLKmode and when we are at the top level.  */
    8911      1960100 :       || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
    8912      1830719 :           && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
    8913            0 :           && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
    8914            0 :               || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
    8915            0 :               || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
    8916              :               != INTEGER_CST)
    8917            0 :           && GET_MODE (x) == BLKmode)
    8918              :       /* If X is in the outgoing argument area, it is always safe.  */
    8919     10593318 :       || (MEM_P (x)
    8920       177813 :           && (XEXP (x, 0) == virtual_outgoing_args_rtx
    8921       177813 :               || (GET_CODE (XEXP (x, 0)) == PLUS
    8922       130205 :                   && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
    8923              :     return true;
    8924              : 
    8925              :   /* If this is a subreg of a hard register, declare it unsafe, otherwise,
    8926              :      find the underlying pseudo.  */
    8927      1960100 :   if (GET_CODE (x) == SUBREG)
    8928              :     {
    8929            0 :       x = SUBREG_REG (x);
    8930            0 :       if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
    8931              :         return false;
    8932              :     }
    8933              : 
    8934              :   /* Now look at our tree code and possibly recurse.  */
    8935      1960100 :   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
    8936              :     {
    8937          492 :     case tcc_declaration:
    8938          492 :       exp_rtl = DECL_RTL_IF_SET (exp);
    8939              :       break;
    8940              : 
    8941              :     case tcc_constant:
    8942              :       return true;
    8943              : 
    8944       853004 :     case tcc_exceptional:
    8945       853004 :       if (TREE_CODE (exp) == TREE_LIST)
    8946              :         {
    8947            0 :           while (1)
    8948              :             {
    8949            0 :               if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
    8950              :                 return false;
    8951            0 :               exp = TREE_CHAIN (exp);
    8952            0 :               if (!exp)
    8953              :                 return true;
    8954            0 :               if (TREE_CODE (exp) != TREE_LIST)
    8955              :                 return safe_from_p (x, exp, 0);
    8956              :             }
    8957              :         }
    8958       853004 :       else if (TREE_CODE (exp) == CONSTRUCTOR)
    8959              :         {
    8960              :           constructor_elt *ce;
    8961              :           unsigned HOST_WIDE_INT idx;
    8962              : 
    8963      7943056 :           FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
    8964         3992 :             if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
    8965       129074 :                 || !safe_from_p (x, ce->value, 0))
    8966       102802 :               return false;
    8967              :           return true;
    8968              :         }
    8969       713604 :       else if (TREE_CODE (exp) == ERROR_MARK)
    8970              :         return true;    /* An already-visited SAVE_EXPR? */
    8971              :       else
    8972              :         return false;
    8973              : 
    8974            0 :     case tcc_statement:
    8975              :       /* The only case we look at here is the DECL_INITIAL inside a
    8976              :          DECL_EXPR.  */
    8977            0 :       return (TREE_CODE (exp) != DECL_EXPR
    8978            0 :               || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
    8979            0 :               || !DECL_INITIAL (DECL_EXPR_DECL (exp))
    8980            0 :               || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
    8981              : 
    8982            0 :     case tcc_binary:
    8983            0 :     case tcc_comparison:
    8984            0 :       if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
    8985              :         return false;
    8986              :       /* Fall through.  */
    8987              : 
    8988           16 :     case tcc_unary:
    8989           16 :       return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
    8990              : 
    8991          367 :     case tcc_expression:
    8992          367 :     case tcc_reference:
    8993          367 :     case tcc_vl_exp:
    8994              :       /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
    8995              :          the expression.  If it is set, we conflict iff we are that rtx or
    8996              :          both are in memory.  Otherwise, we check all operands of the
    8997              :          expression recursively.  */
    8998              : 
    8999          367 :       switch (TREE_CODE (exp))
    9000              :         {
    9001          311 :         case ADDR_EXPR:
    9002              :           /* If the operand is static or we are static, we can't conflict.
    9003              :              Likewise if we don't conflict with the operand at all.  */
    9004          311 :           if (staticp (TREE_OPERAND (exp, 0))
    9005          179 :               || TREE_STATIC (exp)
    9006          490 :               || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
    9007          311 :             return true;
    9008              : 
    9009              :           /* Otherwise, the only way this can conflict is if we are taking
    9010              :              the address of a DECL a that address if part of X, which is
    9011              :              very rare.  */
    9012            0 :           exp = TREE_OPERAND (exp, 0);
    9013            0 :           if (DECL_P (exp))
    9014              :             {
    9015            0 :               if (!DECL_RTL_SET_P (exp)
    9016            0 :                   || !MEM_P (DECL_RTL (exp)))
    9017            0 :                 return false;
    9018              :               else
    9019            0 :                 exp_rtl = XEXP (DECL_RTL (exp), 0);
    9020              :             }
    9021              :           break;
    9022              : 
    9023           41 :         case MEM_REF:
    9024           41 :           if (MEM_P (x)
    9025           41 :               && alias_sets_conflict_p (MEM_ALIAS_SET (x),
    9026              :                                         get_alias_set (exp)))
    9027              :             return false;
    9028              :           break;
    9029              : 
    9030            0 :         case CALL_EXPR:
    9031              :           /* Assume that the call will clobber all hard registers and
    9032              :              all of memory.  */
    9033            0 :           if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
    9034            0 :               || MEM_P (x))
    9035              :             return false;
    9036              :           break;
    9037              : 
    9038            0 :         case WITH_CLEANUP_EXPR:
    9039            0 :         case CLEANUP_POINT_EXPR:
    9040              :           /* Lowered by gimplify.cc.  */
    9041            0 :           gcc_unreachable ();
    9042              : 
    9043            0 :         case SAVE_EXPR:
    9044            0 :           return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
    9045              : 
    9046              :         default:
    9047              :           break;
    9048              :         }
    9049              : 
    9050              :       /* If we have an rtx, we do not need to scan our operands.  */
    9051            0 :       if (exp_rtl)
    9052              :         break;
    9053              : 
    9054           56 :       nops = TREE_OPERAND_LENGTH (exp);
    9055          243 :       for (i = 0; i < nops; i++)
    9056          131 :         if (TREE_OPERAND (exp, i) != 0
    9057          131 :             && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
    9058              :           return false;
    9059              : 
    9060              :       break;
    9061              : 
    9062            0 :     case tcc_type:
    9063              :       /* Should never get a type here.  */
    9064            0 :       gcc_unreachable ();
    9065              :     }
    9066              : 
    9067              :   /* If we have an rtl, find any enclosed object.  Then see if we conflict
    9068              :      with it.  */
    9069          338 :   if (exp_rtl)
    9070              :     {
    9071          282 :       if (GET_CODE (exp_rtl) == SUBREG)
    9072              :         {
    9073            0 :           exp_rtl = SUBREG_REG (exp_rtl);
    9074            0 :           if (REG_P (exp_rtl)
    9075            0 :               && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
    9076              :             return false;
    9077              :         }
    9078              : 
    9079              :       /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
    9080              :          are memory and they conflict.  */
    9081          282 :       return ! (rtx_equal_p (x, exp_rtl)
    9082          282 :                 || (MEM_P (x) && MEM_P (exp_rtl)
    9083            4 :                     && true_dependence (exp_rtl, VOIDmode, x)));
    9084              :     }
    9085              : 
    9086              :   /* If we reach here, it is safe.  */
    9087              :   return true;
    9088              : }
    9089              : 
    9090              : 
    9091              : /* Return the highest power of two that EXP is known to be a multiple of.
    9092              :    This is used in updating alignment of MEMs in array references.  */
    9093              : 
    9094              : unsigned HOST_WIDE_INT
    9095     32403824 : highest_pow2_factor (const_tree exp)
    9096              : {
    9097     32403824 :   unsigned HOST_WIDE_INT ret;
    9098     32403824 :   int trailing_zeros = tree_ctz (exp);
    9099     32403824 :   if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
    9100     44319834 :     return BIGGEST_ALIGNMENT;
    9101      9898028 :   ret = HOST_WIDE_INT_1U << trailing_zeros;
    9102     19325422 :   if (ret > BIGGEST_ALIGNMENT)
    9103     13060694 :     return BIGGEST_ALIGNMENT;
    9104              :   return ret;
    9105              : }
    9106              : 
    9107              : /* Similar, except that the alignment requirements of TARGET are
    9108              :    taken into account.  Assume it is at least as aligned as its
    9109              :    type, unless it is a COMPONENT_REF in which case the layout of
    9110              :    the structure gives the alignment.  */
    9111              : 
    9112              : static unsigned HOST_WIDE_INT
    9113       176508 : highest_pow2_factor_for_target (const_tree target, const_tree exp)
    9114              : {
    9115       176508 :   unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
    9116       176508 :   unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
    9117              : 
    9118       176508 :   return MAX (factor, talign);
    9119              : }
    9120              : 
    9121              : /* Convert the tree comparison code TCODE to the rtl one where the
    9122              :    signedness is UNSIGNEDP.  */
    9123              : 
    9124              : static enum rtx_code
    9125        14417 : convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
    9126              : {
    9127        14417 :   enum rtx_code code;
    9128        14417 :   switch (tcode)
    9129              :     {
    9130              :     case EQ_EXPR:
    9131              :       code = EQ;
    9132              :       break;
    9133          926 :     case NE_EXPR:
    9134          926 :       code = NE;
    9135          926 :       break;
    9136         3205 :     case LT_EXPR:
    9137         3205 :       code = unsignedp ? LTU : LT;
    9138              :       break;
    9139         1787 :     case LE_EXPR:
    9140         1787 :       code = unsignedp ? LEU : LE;
    9141              :       break;
    9142         2179 :     case GT_EXPR:
    9143         2179 :       code = unsignedp ? GTU : GT;
    9144              :       break;
    9145         3499 :     case GE_EXPR:
    9146         3499 :       code = unsignedp ? GEU : GE;
    9147              :       break;
    9148            0 :     case UNORDERED_EXPR:
    9149            0 :       code = UNORDERED;
    9150            0 :       break;
    9151            0 :     case ORDERED_EXPR:
    9152            0 :       code = ORDERED;
    9153            0 :       break;
    9154            0 :     case UNLT_EXPR:
    9155            0 :       code = UNLT;
    9156            0 :       break;
    9157            0 :     case UNLE_EXPR:
    9158            0 :       code = UNLE;
    9159            0 :       break;
    9160            0 :     case UNGT_EXPR:
    9161            0 :       code = UNGT;
    9162            0 :       break;
    9163            0 :     case UNGE_EXPR:
    9164            0 :       code = UNGE;
    9165            0 :       break;
    9166            0 :     case UNEQ_EXPR:
    9167            0 :       code = UNEQ;
    9168            0 :       break;
    9169            0 :     case LTGT_EXPR:
    9170            0 :       code = LTGT;
    9171            0 :       break;
    9172              : 
    9173            0 :     default:
    9174            0 :       gcc_unreachable ();
    9175              :     }
    9176        14417 :   return code;
    9177              : }
    9178              : 
    9179              : /* Subroutine of expand_expr.  Expand the two operands of a binary
    9180              :    expression EXP0 and EXP1 placing the results in OP0 and OP1.
    9181              :    The value may be stored in TARGET if TARGET is nonzero.  The
    9182              :    MODIFIER argument is as documented by expand_expr.  */
    9183              : 
    9184              : void
    9185      8055484 : expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
    9186              :                  enum expand_modifier modifier)
    9187              : {
    9188      8055484 :   if (! safe_from_p (target, exp1, 1))
    9189       594221 :     target = 0;
    9190      8055484 :   if (operand_equal_p (exp0, exp1, 0))
    9191              :     {
    9192        46707 :       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
    9193        46707 :       *op1 = copy_rtx (*op0);
    9194              :     }
    9195              :   else
    9196              :     {
    9197      8008777 :       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
    9198      8008777 :       *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
    9199              :     }
    9200      8055484 : }
    9201              : 
    9202              : 
    9203              : /* Return a MEM that contains constant EXP.  DEFER is as for
    9204              :    output_constant_def and MODIFIER is as for expand_expr.  */
    9205              : 
    9206              : static rtx
    9207      2872429 : expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
    9208              : {
    9209      2872429 :   rtx mem;
    9210              : 
    9211      2872429 :   mem = output_constant_def (exp, defer);
    9212      2872429 :   if (modifier != EXPAND_INITIALIZER)
    9213      1825993 :     mem = use_anchored_address (mem);
    9214      2872429 :   return mem;
    9215              : }
    9216              : 
    9217              : /* A subroutine of expand_expr_addr_expr.  Evaluate the address of EXP.
    9218              :    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
    9219              : 
    9220              : static rtx
    9221     14127918 : expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
    9222              :                          enum expand_modifier modifier, addr_space_t as)
    9223              : {
    9224     14127918 :   rtx result, subtarget;
    9225     14127918 :   tree inner, offset;
    9226     14127918 :   poly_int64 bitsize, bitpos;
    9227     14127918 :   int unsignedp, reversep, volatilep = 0;
    9228     14127918 :   machine_mode mode1;
    9229              : 
    9230              :   /* If we are taking the address of a constant and are at the top level,
    9231              :      we have to use output_constant_def since we can't call force_const_mem
    9232              :      at top level.  */
    9233              :   /* ??? This should be considered a front-end bug.  We should not be
    9234              :      generating ADDR_EXPR of something that isn't an LVALUE.  The only
    9235              :      exception here is STRING_CST.  */
    9236     14127918 :   if (CONSTANT_CLASS_P (exp))
    9237              :     {
    9238      2623690 :       result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
    9239      2623690 :       if (modifier < EXPAND_SUM)
    9240      1735799 :         result = force_operand (result, target);
    9241      2623690 :       return result;
    9242              :     }
    9243              : 
    9244              :   /* Everything must be something allowed by is_gimple_addressable.  */
    9245     11504228 :   switch (TREE_CODE (exp))
    9246              :     {
    9247           36 :     case INDIRECT_REF:
    9248              :       /* This case will happen via recursion for &a->b.  */
    9249           36 :       return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
    9250              : 
    9251       557040 :     case MEM_REF:
    9252       557040 :       {
    9253       557040 :         tree tem = TREE_OPERAND (exp, 0);
    9254       557040 :         if (!integer_zerop (TREE_OPERAND (exp, 1)))
    9255       289143 :           tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
    9256       557040 :         return expand_expr (tem, target, tmode, modifier);
    9257              :       }
    9258              : 
    9259         1151 :     case TARGET_MEM_REF:
    9260         1151 :       return addr_for_mem_ref (exp, as, true);
    9261              : 
    9262        59155 :     case CONST_DECL:
    9263              :       /* Expand the initializer like constants above.  */
    9264        59155 :       result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
    9265              :                                            0, modifier), 0);
    9266        59155 :       if (modifier < EXPAND_SUM)
    9267        59149 :         result = force_operand (result, target);
    9268              :       return result;
    9269              : 
    9270          167 :     case REALPART_EXPR:
    9271              :       /* The real part of the complex number is always first, therefore
    9272              :          the address is the same as the address of the parent object.  */
    9273          167 :       offset = 0;
    9274          167 :       bitpos = 0;
    9275          167 :       inner = TREE_OPERAND (exp, 0);
    9276          167 :       break;
    9277              : 
    9278           84 :     case IMAGPART_EXPR:
    9279              :       /* The imaginary part of the complex number is always second.
    9280              :          The expression is therefore always offset by the size of the
    9281              :          scalar type.  */
    9282           84 :       offset = 0;
    9283          168 :       bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
    9284           84 :       inner = TREE_OPERAND (exp, 0);
    9285           84 :       break;
    9286              : 
    9287           13 :     case COMPOUND_LITERAL_EXPR:
    9288              :       /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
    9289              :          initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
    9290              :          with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
    9291              :          array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
    9292              :          the initializers aren't gimplified.  */
    9293           13 :       if (COMPOUND_LITERAL_EXPR_DECL (exp)
    9294           13 :           && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
    9295           13 :         return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
    9296           13 :                                         target, tmode, modifier, as);
    9297              :       /* FALLTHRU */
    9298     10886582 :     default:
    9299              :       /* If the object is a DECL, then expand it for its rtl.  Don't bypass
    9300              :          expand_expr, as that can have various side effects; LABEL_DECLs for
    9301              :          example, may not have their DECL_RTL set yet.  Expand the rtl of
    9302              :          CONSTRUCTORs too, which should yield a memory reference for the
    9303              :          constructor's contents.  Assume language specific tree nodes can
    9304              :          be expanded in some interesting way.  */
    9305     10886582 :       gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
    9306     10886582 :       if (DECL_P (exp)
    9307      1271357 :           || TREE_CODE (exp) == CONSTRUCTOR
    9308      1271357 :           || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
    9309              :         {
    9310     15732099 :           result = expand_expr (exp, target, tmode,
    9311              :                                 modifier == EXPAND_INITIALIZER
    9312              :                                 ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
    9313              : 
    9314              :           /* If the DECL isn't in memory, then the DECL wasn't properly
    9315              :              marked TREE_ADDRESSABLE, which will be either a front-end
    9316              :              or a tree optimizer bug.  */
    9317              : 
    9318      9615225 :           gcc_assert (MEM_P (result));
    9319      9615224 :           result = XEXP (result, 0);
    9320              : 
    9321              :           /* ??? Is this needed anymore?  */
    9322      9615224 :           if (DECL_P (exp))
    9323      9615224 :             TREE_USED (exp) = 1;
    9324              : 
    9325      9615224 :           if (modifier != EXPAND_INITIALIZER
    9326              :               && modifier != EXPAND_CONST_ADDRESS
    9327      9615224 :               && modifier != EXPAND_SUM)
    9328      4134295 :             result = force_operand (result, target);
    9329      9615224 :           return result;
    9330              :         }
    9331              : 
    9332              :       /* Pass FALSE as the last argument to get_inner_reference although
    9333              :          we are expanding to RTL.  The rationale is that we know how to
    9334              :          handle "aligning nodes" here: we can just bypass them because
    9335              :          they won't change the final object whose address will be returned
    9336              :          (they actually exist only for that purpose).  */
    9337      1271357 :       inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
    9338              :                                    &unsignedp, &reversep, &volatilep);
    9339      1271357 :       break;
    9340              :     }
    9341              : 
    9342              :   /* We must have made progress.  */
    9343      1271608 :   gcc_assert (inner != exp);
    9344              : 
    9345      1271608 :   subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
    9346              :   /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
    9347              :      inner alignment, force the inner to be sufficiently aligned.  */
    9348      1271608 :   if (CONSTANT_CLASS_P (inner)
    9349      1271608 :       && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
    9350              :     {
    9351            0 :       inner = copy_node (inner);
    9352            0 :       TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
    9353            0 :       SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
    9354            0 :       TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
    9355              :     }
    9356      1271608 :   result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
    9357              : 
    9358      1271608 :   if (offset)
    9359              :     {
    9360        51449 :       rtx tmp;
    9361              : 
    9362        51449 :       if (modifier != EXPAND_NORMAL)
    9363         1786 :         result = force_operand (result, NULL);
    9364        53235 :       tmp = expand_expr (offset, NULL_RTX, tmode,
    9365              :                          modifier == EXPAND_INITIALIZER
    9366              :                           ? EXPAND_INITIALIZER : EXPAND_NORMAL);
    9367              : 
    9368              :       /* expand_expr is allowed to return an object in a mode other
    9369              :          than TMODE.  If it did, we need to convert.  */
    9370        51449 :       if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
    9371            0 :         tmp = convert_modes (tmode, GET_MODE (tmp),
    9372            0 :                              tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
    9373        51449 :       result = convert_memory_address_addr_space (tmode, result, as);
    9374        51449 :       tmp = convert_memory_address_addr_space (tmode, tmp, as);
    9375              : 
    9376        51449 :       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
    9377         1786 :         result = simplify_gen_binary (PLUS, tmode, result, tmp);
    9378              :       else
    9379              :         {
    9380        49663 :           subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
    9381        49663 :           result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
    9382              :                                         1, OPTAB_LIB_WIDEN);
    9383              :         }
    9384              :     }
    9385              : 
    9386      1271608 :   if (maybe_ne (bitpos, 0))
    9387              :     {
    9388              :       /* Someone beforehand should have rejected taking the address
    9389              :          of an object that isn't byte-aligned.  */
    9390       611234 :       poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
    9391       611234 :       result = convert_memory_address_addr_space (tmode, result, as);
    9392       611234 :       result = plus_constant (tmode, result, bytepos);
    9393       611234 :       if (modifier < EXPAND_SUM)
    9394       576711 :         result = force_operand (result, target);
    9395              :     }
    9396              : 
    9397              :   return result;
    9398              : }
    9399              : 
    9400              : /* A subroutine of expand_expr.  Evaluate EXP, which is an ADDR_EXPR.
    9401              :    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
    9402              : 
    9403              : static rtx
    9404     12856295 : expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
    9405              :                        enum expand_modifier modifier)
    9406              : {
    9407     12856295 :   addr_space_t as = ADDR_SPACE_GENERIC;
    9408     12856295 :   scalar_int_mode address_mode = Pmode;
    9409     12856295 :   scalar_int_mode pointer_mode = ptr_mode;
    9410     12856295 :   machine_mode rmode;
    9411     12856295 :   rtx result;
    9412              : 
    9413              :   /* Target mode of VOIDmode says "whatever's natural".  */
    9414     12856295 :   if (tmode == VOIDmode)
    9415     10947972 :     tmode = TYPE_MODE (TREE_TYPE (exp));
    9416              : 
    9417     12856295 :   if (POINTER_TYPE_P (TREE_TYPE (exp)))
    9418              :     {
    9419     12856295 :       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
    9420     12856295 :       address_mode = targetm.addr_space.address_mode (as);
    9421     12856295 :       pointer_mode = targetm.addr_space.pointer_mode (as);
    9422              :     }
    9423              : 
    9424              :   /* We can get called with some Weird Things if the user does silliness
    9425              :      like "(short) &a".  In that case, convert_memory_address won't do
    9426              :      the right thing, so ignore the given target mode.  */
    9427     12856295 :   scalar_int_mode new_tmode = (tmode == pointer_mode
    9428     12856295 :                                ? pointer_mode
    9429     12856295 :                                : address_mode);
    9430              : 
    9431     12856295 :   result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
    9432              :                                     new_tmode, modifier, as);
    9433              : 
    9434              :   /* Despite expand_expr claims concerning ignoring TMODE when not
    9435              :      strictly convenient, stuff breaks if we don't honor it.  Note
    9436              :      that combined with the above, we only do this for pointer modes.  */
    9437     12856294 :   rmode = GET_MODE (result);
    9438     12856294 :   if (rmode == VOIDmode)
    9439            6 :     rmode = new_tmode;
    9440     12856294 :   if (rmode != new_tmode)
    9441           74 :     result = convert_memory_address_addr_space (new_tmode, result, as);
    9442              : 
    9443     12856294 :   return result;
    9444              : }
    9445              : 
    9446              : /* Generate code for computing CONSTRUCTOR EXP.
    9447              :    An rtx for the computed value is returned.  If AVOID_TEMP_MEM
    9448              :    is TRUE, instead of creating a temporary variable in memory
    9449              :    NULL is returned and the caller needs to handle it differently.  */
    9450              : 
    9451              : static rtx
    9452       172853 : expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
    9453              :                     bool avoid_temp_mem)
    9454              : {
    9455       172853 :   tree type = TREE_TYPE (exp);
    9456       172853 :   machine_mode mode = TYPE_MODE (type);
    9457              : 
    9458              :   /* Try to avoid creating a temporary at all.  This is possible
    9459              :      if all of the initializer is zero.
    9460              :      FIXME: try to handle all [0..255] initializers we can handle
    9461              :      with memset.  */
    9462       172853 :   if (TREE_STATIC (exp)
    9463         1865 :       && !TREE_ADDRESSABLE (exp)
    9464         1865 :       && target != 0 && mode == BLKmode
    9465       173784 :       && all_zeros_p (exp))
    9466              :     {
    9467          922 :       clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
    9468          922 :       return target;
    9469              :     }
    9470              : 
    9471              :   /* All elts simple constants => refer to a constant in memory.  But
    9472              :      if this is a non-BLKmode mode, let it store a field at a time
    9473              :      since that should make a CONST_INT, CONST_WIDE_INT or
    9474              :      CONST_DOUBLE when we fold.  Likewise, if we have a target we can
    9475              :      use, it is best to store directly into the target unless the type
    9476              :      is large enough that memcpy will be used.  If we are making an
    9477              :      initializer and all operands are constant, put it in memory as
    9478              :      well.
    9479              : 
    9480              :      FIXME: Avoid trying to fill vector constructors piece-meal.
    9481              :      Output them with output_constant_def below unless we're sure
    9482              :      they're zeros.  This should go away when vector initializers
    9483              :      are treated like VECTOR_CST instead of arrays.  */
    9484       171931 :   if ((TREE_STATIC (exp)
    9485          943 :        && ((mode == BLKmode
    9486           46 :             && ! (target != 0 && safe_from_p (target, exp, 1)))
    9487          906 :            || TREE_ADDRESSABLE (exp)
    9488          906 :            || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
    9489          906 :                && (! can_move_by_pieces
    9490          906 :                    (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
    9491          906 :                     TYPE_ALIGN (type)))
    9492            4 :                && ! mostly_zeros_p (exp))))
    9493       172835 :       || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
    9494            0 :           && TREE_CONSTANT (exp)))
    9495              :     {
    9496           39 :       rtx constructor;
    9497              : 
    9498           39 :       if (avoid_temp_mem)
    9499              :         return NULL_RTX;
    9500              : 
    9501           37 :       constructor = expand_expr_constant (exp, 1, modifier);
    9502              : 
    9503           37 :       if (modifier != EXPAND_CONST_ADDRESS
    9504              :           && modifier != EXPAND_INITIALIZER
    9505           37 :           && modifier != EXPAND_SUM)
    9506           37 :         constructor = validize_mem (constructor);
    9507              : 
    9508           37 :       return constructor;
    9509              :     }
    9510              : 
    9511              :   /* If the CTOR is available in static storage and not mostly
    9512              :      zeros and we can move it by pieces prefer to do so since
    9513              :      that's usually more efficient than performing a series of
    9514              :      stores from immediates.  */
    9515       171892 :   if (avoid_temp_mem
    9516           74 :       && TREE_STATIC (exp)
    9517           38 :       && TREE_CONSTANT (exp)
    9518           38 :       && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
    9519           38 :       && can_move_by_pieces (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
    9520           38 :                              TYPE_ALIGN (type))
    9521       171929 :       && ! mostly_zeros_p (exp))
    9522              :     return NULL_RTX;
    9523              : 
    9524              :   /* Handle calls that pass values in multiple non-contiguous
    9525              :      locations.  The Irix 6 ABI has examples of this.  */
    9526       139365 :   if (target == 0 || ! safe_from_p (target, exp, 1)
    9527        36563 :       || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
    9528              :       /* Also make a temporary if the store is to volatile memory, to
    9529              :          avoid individual accesses to aggregate members.  */
    9530       208413 :       || (GET_CODE (target) == MEM
    9531        32574 :           && MEM_VOLATILE_P (target)
    9532          134 :           && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
    9533              :     {
    9534       135439 :       if (avoid_temp_mem)
    9535              :         return NULL_RTX;
    9536              : 
    9537       135428 :       target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
    9538              :     }
    9539              : 
    9540       171851 :   store_constructor (exp, target, 0, int_expr_size (exp), false);
    9541       171851 :   return target;
    9542              : }
    9543              : 
    9544              : 
    9545              : /* expand_expr: generate code for computing expression EXP.
    9546              :    An rtx for the computed value is returned.  The value is never null.
    9547              :    In the case of a void EXP, const0_rtx is returned.
    9548              : 
    9549              :    The value may be stored in TARGET if TARGET is nonzero.
    9550              :    TARGET is just a suggestion; callers must assume that
    9551              :    the rtx returned may not be the same as TARGET.
    9552              : 
    9553              :    If TARGET is CONST0_RTX, it means that the value will be ignored.
    9554              : 
    9555              :    If TMODE is not VOIDmode, it suggests generating the
    9556              :    result in mode TMODE.  But this is done only when convenient.
    9557              :    Otherwise, TMODE is ignored and the value generated in its natural mode.
    9558              :    TMODE is just a suggestion; callers must assume that
    9559              :    the rtx returned may not have mode TMODE.
    9560              : 
    9561              :    Note that TARGET may have neither TMODE nor MODE.  In that case, it
    9562              :    probably will not be used.
    9563              : 
    9564              :    If MODIFIER is EXPAND_SUM then when EXP is an addition
    9565              :    we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
    9566              :    or a nest of (PLUS ...) and (MINUS ...) where the terms are
    9567              :    products as above, or REG or MEM, or constant.
    9568              :    Ordinarily in such cases we would output mul or add instructions
    9569              :    and then return a pseudo reg containing the sum.
    9570              : 
    9571              :    EXPAND_INITIALIZER is much like EXPAND_SUM except that
    9572              :    it also marks a label as absolutely required (it can't be dead).
    9573              :    It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
    9574              :    This is used for outputting expressions used in initializers.
    9575              : 
    9576              :    EXPAND_CONST_ADDRESS says that it is okay to return a MEM
    9577              :    with a constant address even if that address is not normally legitimate.
    9578              :    EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
    9579              : 
    9580              :    EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
    9581              :    a call parameter.  Such targets require special care as we haven't yet
    9582              :    marked TARGET so that it's safe from being trashed by libcalls.  We
    9583              :    don't want to use TARGET for anything but the final result;
    9584              :    Intermediate values must go elsewhere.   Additionally, calls to
    9585              :    emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
    9586              : 
    9587              :    If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
    9588              :    address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
    9589              :    DECL_RTL of the VAR_DECL.  *ALT_RTL is also set if EXP is a
    9590              :    COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
    9591              :    recursively.
    9592              :    If the result can be stored at TARGET, and ALT_RTL is non-NULL,
    9593              :    then *ALT_RTL is set to TARGET (before legitimziation).
    9594              : 
    9595              :    If INNER_REFERENCE_P is true, we are expanding an inner reference.
    9596              :    In this case, we don't adjust a returned MEM rtx that wouldn't be
    9597              :    sufficiently aligned for its mode; instead, it's up to the caller
    9598              :    to deal with it afterwards.  This is used to make sure that unaligned
    9599              :    base objects for which out-of-bounds accesses are supported, for
    9600              :    example record types with trailing arrays, aren't realigned behind
    9601              :    the back of the caller.
    9602              :    The normal operating mode is to pass FALSE for this parameter.  */
    9603              : 
    9604              : rtx
    9605    154526798 : expand_expr_real (tree exp, rtx target, machine_mode tmode,
    9606              :                   enum expand_modifier modifier, rtx *alt_rtl,
    9607              :                   bool inner_reference_p)
    9608              : {
    9609    154526798 :   rtx ret;
    9610              : 
    9611              :   /* Handle ERROR_MARK before anybody tries to access its type.  */
    9612    154526798 :   if (TREE_CODE (exp) == ERROR_MARK
    9613    154526798 :       || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
    9614              :     {
    9615            0 :       ret = CONST0_RTX (tmode);
    9616            0 :       return ret ? ret : const0_rtx;
    9617              :     }
    9618              : 
    9619    154526798 :   ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
    9620              :                             inner_reference_p);
    9621    154526798 :   return ret;
    9622              : }
    9623              : 
    9624              : /* Try to expand the conditional expression which is represented by
    9625              :    TREEOP0 ? TREEOP1 : TREEOP2 using conditonal moves.  If it succeeds
    9626              :    return the rtl reg which represents the result.  Otherwise return
    9627              :    NULL_RTX.  */
    9628              : 
    9629              : static rtx
    9630        17867 : expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
    9631              :                               tree treeop1 ATTRIBUTE_UNUSED,
    9632              :                               tree treeop2 ATTRIBUTE_UNUSED)
    9633              : {
    9634        17867 :   rtx insn;
    9635        17867 :   rtx op00, op01, op1, op2;
    9636        17867 :   enum rtx_code comparison_code;
    9637        17867 :   machine_mode comparison_mode;
    9638        17867 :   gimple *srcstmt;
    9639        17867 :   rtx temp;
    9640        17867 :   tree type = TREE_TYPE (treeop1);
    9641        17867 :   int unsignedp = TYPE_UNSIGNED (type);
    9642        17867 :   machine_mode mode = TYPE_MODE (type);
    9643        17867 :   machine_mode orig_mode = mode;
    9644        17867 :   static bool expanding_cond_expr_using_cmove = false;
    9645              : 
    9646              :   /* Conditional move expansion can end up TERing two operands which,
    9647              :      when recursively hitting conditional expressions can result in
    9648              :      exponential behavior if the cmove expansion ultimatively fails.
    9649              :      It's hardly profitable to TER a cmove into a cmove so avoid doing
    9650              :      that by failing early if we end up recursing.  */
    9651        17867 :   if (expanding_cond_expr_using_cmove)
    9652              :     return NULL_RTX;
    9653              : 
    9654              :   /* If we cannot do a conditional move on the mode, try doing it
    9655              :      with the promoted mode. */
    9656        16901 :   if (!can_conditionally_move_p (mode))
    9657              :     {
    9658          241 :       mode = promote_mode (type, mode, &unsignedp);
    9659          241 :       if (!can_conditionally_move_p (mode))
    9660              :         return NULL_RTX;
    9661            0 :       temp = assign_temp (type, 0, 0); /* Use promoted mode for temp.  */
    9662              :     }
    9663              :   else
    9664        16660 :     temp = assign_temp (type, 0, 1);
    9665              : 
    9666        16660 :   expanding_cond_expr_using_cmove = true;
    9667        16660 :   start_sequence ();
    9668        16660 :   expand_operands (treeop1, treeop2,
    9669              :                    mode == orig_mode ? temp : NULL_RTX, &op1, &op2,
    9670              :                    EXPAND_NORMAL);
    9671              : 
    9672        16660 :   if (TREE_CODE (treeop0) == SSA_NAME
    9673        16535 :       && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))
    9674        30955 :       && !VECTOR_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (srcstmt))))
    9675              :     {
    9676        14292 :       type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
    9677        14292 :       enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt);
    9678        14292 :       op00 = expand_normal (gimple_assign_rhs1 (srcstmt));
    9679        14292 :       op01 = expand_normal (gimple_assign_rhs2 (srcstmt));
    9680        14292 :       comparison_mode = TYPE_MODE (type);
    9681        14292 :       unsignedp = TYPE_UNSIGNED (type);
    9682        14292 :       comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
    9683              :     }
    9684         2368 :   else if (COMPARISON_CLASS_P (treeop0)
    9685         2368 :            && !VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (treeop0, 0))))
    9686              :     {
    9687          125 :       type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
    9688          125 :       enum tree_code cmpcode = TREE_CODE (treeop0);
    9689          125 :       op00 = expand_normal (TREE_OPERAND (treeop0, 0));
    9690          125 :       op01 = expand_normal (TREE_OPERAND (treeop0, 1));
    9691          125 :       unsignedp = TYPE_UNSIGNED (type);
    9692          125 :       comparison_mode = TYPE_MODE (type);
    9693          125 :       comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
    9694              :     }
    9695              :   else
    9696              :     {
    9697         2243 :       op00 = expand_normal (treeop0);
    9698         2243 :       op01 = const0_rtx;
    9699         2243 :       comparison_code = NE;
    9700         2243 :       comparison_mode = GET_MODE (op00);
    9701         2243 :       if (comparison_mode == VOIDmode)
    9702            0 :         comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
    9703              :     }
    9704        16660 :   expanding_cond_expr_using_cmove = false;
    9705              : 
    9706        16660 :   if (GET_MODE (op1) != mode)
    9707         2316 :     op1 = gen_lowpart (mode, op1);
    9708              : 
    9709        16660 :   if (GET_MODE (op2) != mode)
    9710         8963 :     op2 = gen_lowpart (mode, op2);
    9711              : 
    9712              :   /* Try to emit the conditional move.  */
    9713        16660 :   insn = emit_conditional_move (temp,
    9714              :                                 { comparison_code, op00, op01,
    9715              :                                   comparison_mode },
    9716              :                                 op1, op2, mode,
    9717              :                                 unsignedp);
    9718              : 
    9719              :   /* If we could do the conditional move, emit the sequence,
    9720              :      and return.  */
    9721        16660 :   if (insn)
    9722              :     {
    9723        14101 :       rtx_insn *seq = end_sequence ();
    9724        14101 :       emit_insn (seq);
    9725        14101 :       return convert_modes (orig_mode, mode, temp, 0);
    9726              :     }
    9727              : 
    9728              :   /* Otherwise discard the sequence and fall back to code with
    9729              :      branches.  */
    9730         2559 :   end_sequence ();
    9731         2559 :   return NULL_RTX;
    9732              : }
    9733              : 
    9734              : /* A helper function for expand_expr_real_2 to be used with a
    9735              :    misaligned mem_ref TEMP.  Assume an unsigned type if UNSIGNEDP
    9736              :    is nonzero, with alignment ALIGN in bits.
    9737              :    Store the value at TARGET if possible (if TARGET is nonzero).
    9738              :    Regardless of TARGET, we return the rtx for where the value is placed.
    9739              :    If the result can be stored at TARGET, and ALT_RTL is non-NULL,
    9740              :    then *ALT_RTL is set to TARGET (before legitimziation).  */
    9741              : 
    9742              : static rtx
    9743       206359 : expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
    9744              :                            unsigned int align, rtx target, rtx *alt_rtl)
    9745              : {
    9746       206359 :   enum insn_code icode;
    9747              : 
    9748       206359 :   if ((icode = optab_handler (movmisalign_optab, mode))
    9749              :       != CODE_FOR_nothing)
    9750              :     {
    9751       130520 :       class expand_operand ops[2];
    9752              : 
    9753              :       /* We've already validated the memory, and we're creating a
    9754              :          new pseudo destination.  The predicates really can't fail,
    9755              :          nor can the generator.  */
    9756       130520 :       create_output_operand (&ops[0], NULL_RTX, mode);
    9757       130520 :       create_fixed_operand (&ops[1], temp);
    9758       130520 :       expand_insn (icode, 2, ops);
    9759       130520 :       temp = ops[0].value;
    9760              :     }
    9761        75839 :   else if (targetm.slow_unaligned_access (mode, align))
    9762            0 :     temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
    9763              :                               0, unsignedp, target,
    9764              :                               mode, mode, false, alt_rtl);
    9765       206359 :   return temp;
    9766              : }
    9767              : 
    9768              : /* Helper function of expand_expr_2, expand a division or modulo.
    9769              :    op0 and op1 should be already expanded treeop0 and treeop1, using
    9770              :    expand_operands.  */
    9771              : 
    9772              : static rtx
    9773       153819 : expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
    9774              :                     tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
    9775              : {
    9776       307638 :   bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
    9777       153819 :                 || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
    9778       153819 :   if (SCALAR_INT_MODE_P (mode)
    9779       153819 :       && optimize >= 2
    9780       127503 :       && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1
    9781       185025 :       && get_range_pos_neg (treeop1, currently_expanding_gimple_stmt) == 1)
    9782              :     {
    9783              :       /* If both arguments are known to be positive when interpreted
    9784              :          as signed, we can expand it as both signed and unsigned
    9785              :          division or modulo.  Choose the cheaper sequence in that case.  */
    9786        17906 :       bool speed_p = optimize_insn_for_speed_p ();
    9787        17906 :       do_pending_stack_adjust ();
    9788        17906 :       start_sequence ();
    9789        17906 :       rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
    9790        17906 :       rtx_insn *uns_insns = end_sequence ();
    9791        17906 :       start_sequence ();
    9792        17906 :       rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
    9793        17906 :       rtx_insn *sgn_insns = end_sequence ();
    9794        17906 :       unsigned uns_cost = seq_cost (uns_insns, speed_p);
    9795        17906 :       unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
    9796        17906 :       bool was_tie = false;
    9797              : 
    9798              :       /* If costs are the same then use as tie breaker the other other
    9799              :          factor.  */
    9800        17906 :       if (uns_cost == sgn_cost)
    9801              :         {
    9802         6943 :           uns_cost = seq_cost (uns_insns, !speed_p);
    9803         6943 :           sgn_cost = seq_cost (sgn_insns, !speed_p);
    9804         6943 :           was_tie = true;
    9805              :         }
    9806              : 
    9807        17906 :       if (dump_file && (dump_flags & TDF_DETAILS))
    9808            0 :         fprintf (dump_file, ";; positive division:%s unsigned cost: %u; "
    9809              :                             "signed cost: %u\n",
    9810              :                  was_tie ? " (needed tie breaker)" : "", uns_cost, sgn_cost);
    9811              : 
    9812        17906 :       if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
    9813              :         {
    9814        11774 :           emit_insn (uns_insns);
    9815        11774 :           return uns_ret;
    9816              :         }
    9817         6132 :       emit_insn (sgn_insns);
    9818         6132 :       return sgn_ret;
    9819              :     }
    9820       135913 :   return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
    9821              : }
    9822              : 
    9823              : /* Return true if EXP has a range of values [0..1], false
    9824              :    otherwise. This works for constants and ssa names, calling back into the ranger.  */
    9825              : static bool
    9826      1447650 : expr_has_boolean_range (tree exp, gimple *stmt)
    9827              : {
    9828              :   /* An integral type with a single bit of precision.  */
    9829      2895287 :   if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
    9830      1447650 :       && TYPE_UNSIGNED (TREE_TYPE (exp))
    9831      2437908 :       && TYPE_PRECISION (TREE_TYPE (exp)) == 1)
    9832              :     return true;
    9833              : 
    9834              :   /* Signed 1 bit integers are not boolean ranges. */
    9835      2895287 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
    9836      2895287 :       || TYPE_PRECISION (TREE_TYPE (exp)) <= 1)
    9837              :     return false;
    9838              : 
    9839      1447650 :   if (TREE_CODE (exp) == SSA_NAME)
    9840       844803 :     return ssa_name_has_boolean_range (exp, stmt);
    9841       602847 :   if (TREE_CODE (exp) == INTEGER_CST)
    9842       531839 :     return wi::leu_p (wi::to_wide (exp), 1);
    9843              :   return false;
    9844              : }
    9845              : 
    9846              : rtx
    9847     13212038 : expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
    9848              :                     enum expand_modifier modifier)
    9849              : {
    9850     13212038 :   rtx op0, op1, op2, temp;
    9851     13212038 :   rtx_code_label *lab;
    9852     13212038 :   tree type;
    9853     13212038 :   int unsignedp;
    9854     13212038 :   machine_mode mode;
    9855     13212038 :   scalar_int_mode int_mode;
    9856     13212038 :   enum tree_code code = ops->code;
    9857     13212038 :   optab this_optab;
    9858     13212038 :   rtx subtarget, original_target;
    9859     13212038 :   int ignore;
    9860     13212038 :   bool reduce_bit_field;
    9861     13212038 :   location_t loc = ops->location;
    9862     13212038 :   tree treeop0, treeop1, treeop2;
    9863              : #define REDUCE_BIT_FIELD(expr)  (reduce_bit_field                         \
    9864              :                                  ? reduce_to_bit_field_precision ((expr), \
    9865              :                                                                   target, \
    9866              :                                                                   type)   \
    9867              :                                  : (expr))
    9868              : 
    9869     13212038 :   type = ops->type;
    9870     13212038 :   mode = TYPE_MODE (type);
    9871     13212038 :   unsignedp = TYPE_UNSIGNED (type);
    9872              : 
    9873     13212038 :   treeop0 = ops->op0;
    9874     13212038 :   treeop1 = ops->op1;
    9875     13212038 :   treeop2 = ops->op2;
    9876              : 
    9877              :   /* We should be called only on simple (binary or unary) expressions,
    9878              :      exactly those that are valid in gimple expressions that aren't
    9879              :      GIMPLE_SINGLE_RHS (or invalid).  */
    9880     13212038 :   gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
    9881              :               || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
    9882              :               || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
    9883              : 
    9884     26424076 :   ignore = (target == const0_rtx
    9885     13212038 :             || ((CONVERT_EXPR_CODE_P (code)
    9886      9494699 :                  || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
    9887      3735206 :                 && TREE_CODE (type) == VOID_TYPE));
    9888              : 
    9889              :   /* We should be called only if we need the result.  */
    9890            0 :   gcc_assert (!ignore);
    9891              : 
    9892              :   /* An operation in what may be a bit-field type needs the
    9893              :      result to be reduced to the precision of the bit-field type,
    9894              :      which is narrower than that of the type's mode.  */
    9895     27192235 :   reduce_bit_field = (INTEGRAL_TYPE_P (type)
    9896     13212038 :                       && !type_has_mode_precision_p (type));
    9897              : 
    9898       768159 :   if (reduce_bit_field
    9899       768159 :       && (modifier == EXPAND_STACK_PARM
    9900       767635 :           || (target && GET_MODE (target) != mode)))
    9901       461147 :     target = 0;
    9902              : 
    9903              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
    9904     13212038 :   subtarget = get_subtarget (target);
    9905     13212038 :   original_target = target;
    9906              : 
    9907     13212038 :   switch (code)
    9908              :     {
    9909      3720539 :     case NON_LVALUE_EXPR:
    9910      3720539 :     case PAREN_EXPR:
    9911      3720539 :     CASE_CONVERT:
    9912      3720539 :       if (treeop0 == error_mark_node)
    9913            0 :         return const0_rtx;
    9914              : 
    9915      3720539 :       if (TREE_CODE (type) == UNION_TYPE)
    9916              :         {
    9917            0 :           tree valtype = TREE_TYPE (treeop0);
    9918              : 
    9919              :           /* If both input and output are BLKmode, this conversion isn't doing
    9920              :              anything except possibly changing memory attribute.  */
    9921            0 :           if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
    9922              :             {
    9923            0 :               rtx result = expand_expr (treeop0, target, tmode,
    9924              :                                         modifier);
    9925              : 
    9926            0 :               result = copy_rtx (result);
    9927            0 :               set_mem_attributes (result, type, 0);
    9928            0 :               return result;
    9929              :             }
    9930              : 
    9931            0 :           if (target == 0)
    9932              :             {
    9933            0 :               if (TYPE_MODE (type) != BLKmode)
    9934            0 :                 target = gen_reg_rtx (TYPE_MODE (type));
    9935              :               else
    9936            0 :                 target = assign_temp (type, 1, 1);
    9937              :             }
    9938              : 
    9939            0 :           if (MEM_P (target))
    9940              :             /* Store data into beginning of memory target.  */
    9941            0 :             store_expr (treeop0,
    9942            0 :                         adjust_address (target, TYPE_MODE (valtype), 0),
    9943              :                         modifier == EXPAND_STACK_PARM,
    9944            0 :                         false, TYPE_REVERSE_STORAGE_ORDER (type));
    9945              : 
    9946              :           else
    9947              :             {
    9948            0 :               gcc_assert (REG_P (target)
    9949              :                           && !TYPE_REVERSE_STORAGE_ORDER (type));
    9950              : 
    9951              :               /* Store this field into a union of the proper type.  */
    9952            0 :               poly_uint64 op0_size
    9953            0 :                 = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
    9954            0 :               poly_uint64 union_size = GET_MODE_BITSIZE (mode);
    9955            0 :               store_field (target,
    9956              :                            /* The conversion must be constructed so that
    9957              :                               we know at compile time how many bits
    9958              :                               to preserve.  */
    9959            0 :                            ordered_min (op0_size, union_size),
    9960            0 :                            0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
    9961              :                            false, false);
    9962              :             }
    9963              : 
    9964              :           /* Return the entire union.  */
    9965            0 :           return target;
    9966              :         }
    9967              : 
    9968      3720539 :       if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
    9969              :         {
    9970      2196610 :           op0 = expand_expr (treeop0, target, VOIDmode,
    9971              :                              modifier);
    9972              : 
    9973      2196610 :           return REDUCE_BIT_FIELD (op0);
    9974              :         }
    9975              : 
    9976      1882814 :       op0 = expand_expr (treeop0, NULL_RTX, mode,
    9977              :                          modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
    9978      1523929 :       if (GET_MODE (op0) == mode)
    9979              :         ;
    9980              : 
    9981              :       /* If OP0 is a constant, just convert it into the proper mode.  */
    9982      1483872 :       else if (CONSTANT_P (op0))
    9983              :         {
    9984          900 :           tree inner_type = TREE_TYPE (treeop0);
    9985          900 :           machine_mode inner_mode = GET_MODE (op0);
    9986              : 
    9987          900 :           if (inner_mode == VOIDmode)
    9988           15 :             inner_mode = TYPE_MODE (inner_type);
    9989              : 
    9990          900 :           if (modifier == EXPAND_INITIALIZER)
    9991            0 :             op0 = force_lowpart_subreg (mode, op0, inner_mode);
    9992              :           else
    9993          900 :             op0 = convert_modes (mode, inner_mode, op0,
    9994          900 :                                  TYPE_UNSIGNED (inner_type));
    9995              :         }
    9996              : 
    9997      1482972 :       else if (modifier == EXPAND_INITIALIZER)
    9998           24 :         op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
    9999              :                              ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
   10000              : 
   10001      1482960 :       else if (SCALAR_INT_MODE_P (GET_MODE (op0))
   10002      1310484 :                && optimize >= 2
   10003       778579 :                && SCALAR_INT_MODE_P (mode)
   10004       778579 :                && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
   10005       778381 :                && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
   10006      1556762 :                    > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
   10007      2033250 :                && get_range_pos_neg (treeop0,
   10008              :                                      currently_expanding_gimple_stmt) == 1)
   10009              :         {
   10010              :           /* If argument is known to be positive when interpreted
   10011              :              as signed, we can expand it as both sign and zero
   10012              :              extension.  Choose the cheaper sequence in that case.  */
   10013       143848 :           bool speed_p = optimize_insn_for_speed_p ();
   10014       143848 :           rtx uns_ret = NULL_RTX, sgn_ret = NULL_RTX;
   10015       143848 :           do_pending_stack_adjust ();
   10016       143848 :           start_sequence ();
   10017       143848 :           if (target == NULL_RTX)
   10018       117423 :             uns_ret = convert_to_mode (mode, op0, 1);
   10019              :           else
   10020        26425 :             convert_move (target, op0, 1);
   10021       143848 :           rtx_insn *uns_insns = end_sequence ();
   10022       143848 :           start_sequence ();
   10023       143848 :           if (target == NULL_RTX)
   10024       117423 :             sgn_ret = convert_to_mode (mode, op0, 0);
   10025              :           else
   10026        26425 :             convert_move (target, op0, 0);
   10027       143848 :           rtx_insn *sgn_insns = end_sequence ();
   10028       143848 :           unsigned uns_cost = seq_cost (uns_insns, speed_p);
   10029       143848 :           unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
   10030       143848 :           bool was_tie = false;
   10031              : 
   10032              :           /* If costs are the same then use as tie breaker the other other
   10033              :              factor.  */
   10034       143848 :           if (uns_cost == sgn_cost)
   10035              :             {
   10036        39617 :               uns_cost = seq_cost (uns_insns, !speed_p);
   10037        39617 :               sgn_cost = seq_cost (sgn_insns, !speed_p);
   10038        39617 :               was_tie = true;
   10039              :             }
   10040              : 
   10041       143848 :           if (dump_file && (dump_flags & TDF_DETAILS))
   10042            0 :             fprintf (dump_file, ";; positive extension:%s unsigned cost: %u; "
   10043              :                                 "signed cost: %u\n",
   10044              :                      was_tie ? " (needed tie breaker)" : "",
   10045              :                      uns_cost, sgn_cost);
   10046       143848 :           if (uns_cost < sgn_cost
   10047       143848 :               || (uns_cost == sgn_cost && TYPE_UNSIGNED (TREE_TYPE (treeop0))))
   10048              :             {
   10049       129217 :               emit_insn (uns_insns);
   10050       129217 :               sgn_ret = uns_ret;
   10051              :             }
   10052              :           else
   10053        14631 :             emit_insn (sgn_insns);
   10054       143848 :           if (target == NULL_RTX)
   10055       117423 :             op0 = sgn_ret;
   10056              :           else
   10057        26425 :             op0 = target;
   10058              :         }
   10059      1339112 :       else if (target == 0)
   10060       849610 :         op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10061              :       else
   10062              :         {
   10063       489502 :           convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10064       489502 :           op0 = target;
   10065              :         }
   10066              : 
   10067      1523929 :       return REDUCE_BIT_FIELD (op0);
   10068              : 
   10069            0 :     case ADDR_SPACE_CONVERT_EXPR:
   10070            0 :       {
   10071            0 :         tree treeop0_type = TREE_TYPE (treeop0);
   10072              : 
   10073            0 :         gcc_assert (POINTER_TYPE_P (type));
   10074            0 :         gcc_assert (POINTER_TYPE_P (treeop0_type));
   10075              : 
   10076            0 :         addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
   10077            0 :         addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
   10078              : 
   10079              :         /* Conversions between pointers to the same address space should
   10080              :            have been implemented via CONVERT_EXPR / NOP_EXPR.  */
   10081            0 :         gcc_assert (as_to != as_from);
   10082              : 
   10083            0 :         op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
   10084              : 
   10085              :         /* Ask target code to handle conversion between pointers
   10086              :            to overlapping address spaces.  */
   10087            0 :         if (targetm.addr_space.subset_p (as_to, as_from)
   10088            0 :             || targetm.addr_space.subset_p (as_from, as_to))
   10089              :           {
   10090            0 :             op0 = targetm.addr_space.convert (op0, treeop0_type, type);
   10091              :           }
   10092              :         else
   10093              :           {
   10094              :             /* For disjoint address spaces, converting anything but a null
   10095              :                pointer invokes undefined behavior.  We truncate or extend the
   10096              :                value as if we'd converted via integers, which handles 0 as
   10097              :                required, and all others as the programmer likely expects.  */
   10098              : #ifndef POINTERS_EXTEND_UNSIGNED
   10099              :             const int POINTERS_EXTEND_UNSIGNED = 1;
   10100              : #endif
   10101            0 :             op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
   10102              :                                  op0, POINTERS_EXTEND_UNSIGNED);
   10103              :           }
   10104            0 :         gcc_assert (op0);
   10105              :         return op0;
   10106              :       }
   10107              : 
   10108      1349049 :     case POINTER_PLUS_EXPR:
   10109              :       /* Even though the sizetype mode and the pointer's mode can be different
   10110              :          expand is able to handle this correctly and get the correct result out
   10111              :          of the PLUS_EXPR code.  */
   10112              :       /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
   10113              :          if sizetype precision is smaller than pointer precision.  */
   10114      1349049 :       if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
   10115            0 :         treeop1 = fold_convert_loc (loc, type,
   10116              :                                     fold_convert_loc (loc, ssizetype,
   10117              :                                                       treeop1));
   10118              :       /* If sizetype precision is larger than pointer precision, truncate the
   10119              :          offset to have matching modes.  */
   10120      1349049 :       else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
   10121            0 :         treeop1 = fold_convert_loc (loc, type, treeop1);
   10122              :       /* FALLTHRU */
   10123              : 
   10124      5295971 :     case PLUS_EXPR:
   10125              :       /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
   10126              :          something else, make sure we add the register to the constant and
   10127              :          then to the other thing.  This case can occur during strength
   10128              :          reduction and doing it this way will produce better code if the
   10129              :          frame pointer or argument pointer is eliminated.
   10130              : 
   10131              :          fold-const.cc will ensure that the constant is always in the inner
   10132              :          PLUS_EXPR, so the only case we need to do anything about is if
   10133              :          sp, ap, or fp is our second argument, in which case we must swap
   10134              :          the innermost first argument and our second argument.  */
   10135              : 
   10136      5295971 :       if (TREE_CODE (treeop0) == PLUS_EXPR
   10137         6971 :           && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
   10138            0 :           && VAR_P (treeop1)
   10139      5295971 :           && (DECL_RTL (treeop1) == frame_pointer_rtx
   10140            0 :               || DECL_RTL (treeop1) == stack_pointer_rtx
   10141            0 :               || DECL_RTL (treeop1) == arg_pointer_rtx))
   10142              :         {
   10143            0 :           gcc_unreachable ();
   10144              :         }
   10145              : 
   10146              :       /* If the result is to be ptr_mode and we are adding an integer to
   10147              :          something, we might be forming a constant.  So try to use
   10148              :          plus_constant.  If it produces a sum and we can't accept it,
   10149              :          use force_operand.  This allows P = &ARR[const] to generate
   10150              :          efficient code on machines where a SYMBOL_REF is not a valid
   10151              :          address.
   10152              : 
   10153              :          If this is an EXPAND_SUM call, always return the sum.  */
   10154      5295971 :       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
   10155      5295971 :           || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
   10156              :         {
   10157      3440662 :           if (modifier == EXPAND_STACK_PARM)
   10158        18563 :             target = 0;
   10159      3440662 :           if (TREE_CODE (treeop0) == INTEGER_CST
   10160      3441669 :               && HWI_COMPUTABLE_MODE_P (mode)
   10161      3441673 :               && TREE_CONSTANT (treeop1))
   10162              :             {
   10163            4 :               rtx constant_part;
   10164            4 :               HOST_WIDE_INT wc;
   10165            4 :               machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
   10166              : 
   10167            4 :               op1 = expand_expr (treeop1, subtarget, VOIDmode,
   10168              :                                  EXPAND_SUM);
   10169              :               /* Use wi::shwi to ensure that the constant is
   10170              :                  truncated according to the mode of OP1, then sign extended
   10171              :                  to a HOST_WIDE_INT.  Using the constant directly can result
   10172              :                  in non-canonical RTL in a 64x32 cross compile.  */
   10173            4 :               wc = TREE_INT_CST_LOW (treeop0);
   10174            4 :               constant_part =
   10175            4 :                 immed_wide_int_const (wi::shwi (wc, wmode), wmode);
   10176            4 :               op1 = plus_constant (mode, op1, INTVAL (constant_part));
   10177            4 :               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
   10178            1 :                 op1 = force_operand (op1, target);
   10179            4 :               return REDUCE_BIT_FIELD (op1);
   10180              :             }
   10181              : 
   10182      3440658 :           else if (TREE_CODE (treeop1) == INTEGER_CST
   10183      7343658 :                    && HWI_COMPUTABLE_MODE_P (mode)
   10184      5760317 :                    && TREE_CONSTANT (treeop0))
   10185              :             {
   10186       271968 :               rtx constant_part;
   10187       271968 :               HOST_WIDE_INT wc;
   10188       271968 :               machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
   10189              : 
   10190       474074 :               op0 = expand_expr (treeop0, subtarget, VOIDmode,
   10191              :                                  (modifier == EXPAND_INITIALIZER
   10192              :                                  ? EXPAND_INITIALIZER : EXPAND_SUM));
   10193       271968 :               if (! CONSTANT_P (op0))
   10194              :                 {
   10195            6 :                   op1 = expand_expr (treeop1, NULL_RTX,
   10196              :                                      VOIDmode, modifier);
   10197              :                   /* Return a PLUS if modifier says it's OK.  */
   10198            6 :                   if (modifier == EXPAND_SUM
   10199              :                       || modifier == EXPAND_INITIALIZER)
   10200            6 :                     return simplify_gen_binary (PLUS, mode, op0, op1);
   10201            0 :                   goto binop2;
   10202              :                 }
   10203              :               /* Use wi::shwi to ensure that the constant is
   10204              :                  truncated according to the mode of OP1, then sign extended
   10205              :                  to a HOST_WIDE_INT.  Using the constant directly can result
   10206              :                  in non-canonical RTL in a 64x32 cross compile.  */
   10207       271962 :               wc = TREE_INT_CST_LOW (treeop1);
   10208       271962 :               constant_part
   10209       271962 :                 = immed_wide_int_const (wi::shwi (wc, wmode), wmode);
   10210       271962 :               op0 = plus_constant (mode, op0, INTVAL (constant_part));
   10211       271962 :               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
   10212       201308 :                 op0 = force_operand (op0, target);
   10213       271962 :               return REDUCE_BIT_FIELD (op0);
   10214              :             }
   10215              :         }
   10216              : 
   10217              :       /* Use TER to expand pointer addition of a negated value
   10218              :          as pointer subtraction.  */
   10219      8986922 :       if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
   10220      3946909 :            || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
   10221        79633 :                && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
   10222      1077090 :           && TREE_CODE (treeop1) == SSA_NAME
   10223      6156665 :           && TYPE_MODE (TREE_TYPE (treeop0))
   10224       566333 :              == TYPE_MODE (TREE_TYPE (treeop1)))
   10225              :         {
   10226       566333 :           gimple *def = get_def_for_expr (treeop1, NEGATE_EXPR);
   10227       566333 :           if (def)
   10228              :             {
   10229         2481 :               treeop1 = gimple_assign_rhs1 (def);
   10230         2481 :               code = MINUS_EXPR;
   10231         2481 :               goto do_minus;
   10232              :             }
   10233              :         }
   10234              : 
   10235              :       /* No sense saving up arithmetic to be done
   10236              :          if it's all in the wrong mode to form part of an address.
   10237              :          And force_operand won't know whether to sign-extend or
   10238              :          zero-extend.  */
   10239      5021518 :       if (modifier != EXPAND_INITIALIZER
   10240      5021518 :           && (modifier != EXPAND_SUM || mode != ptr_mode))
   10241              :         {
   10242      4452247 :           expand_operands (treeop0, treeop1,
   10243              :                            subtarget, &op0, &op1, modifier);
   10244      4452247 :           if (op0 == const0_rtx)
   10245         8670 :             return op1;
   10246      4443577 :           if (op1 == const0_rtx)
   10247              :             return op0;
   10248      4443325 :           goto binop2;
   10249              :         }
   10250              : 
   10251       569271 :       expand_operands (treeop0, treeop1,
   10252              :                        subtarget, &op0, &op1, modifier);
   10253       569271 :       return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
   10254              : 
   10255       517707 :     case MINUS_EXPR:
   10256       517707 :     case POINTER_DIFF_EXPR:
   10257       517707 :     do_minus:
   10258              :       /* For initializers, we are allowed to return a MINUS of two
   10259              :          symbolic constants.  Here we handle all cases when both operands
   10260              :          are constant.  */
   10261              :       /* Handle difference of two symbolic constants,
   10262              :          for the sake of an initializer.  */
   10263       517707 :       if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
   10264         3165 :           && really_constant_p (treeop0)
   10265       518203 :           && really_constant_p (treeop1))
   10266              :         {
   10267           68 :           expand_operands (treeop0, treeop1,
   10268              :                            NULL_RTX, &op0, &op1, modifier);
   10269           68 :           return simplify_gen_binary (MINUS, mode, op0, op1);
   10270              :         }
   10271              : 
   10272              :       /* No sense saving up arithmetic to be done
   10273              :          if it's all in the wrong mode to form part of an address.
   10274              :          And force_operand won't know whether to sign-extend or
   10275              :          zero-extend.  */
   10276       517639 :       if (modifier != EXPAND_INITIALIZER
   10277       517639 :           && (modifier != EXPAND_SUM || mode != ptr_mode))
   10278       514542 :         goto binop;
   10279              : 
   10280         3097 :       expand_operands (treeop0, treeop1,
   10281              :                        subtarget, &op0, &op1, modifier);
   10282              : 
   10283              :       /* Convert A - const to A + (-const).  */
   10284         3097 :       if (CONST_INT_P (op1))
   10285              :         {
   10286            0 :           op1 = negate_rtx (mode, op1);
   10287            0 :           return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
   10288              :         }
   10289              : 
   10290         3097 :       goto binop2;
   10291              : 
   10292            0 :     case WIDEN_MULT_PLUS_EXPR:
   10293            0 :     case WIDEN_MULT_MINUS_EXPR:
   10294            0 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   10295            0 :       op2 = expand_normal (treeop2);
   10296            0 :       target = expand_widen_pattern_expr (ops, op0, op1, op2,
   10297              :                                           target, unsignedp);
   10298            0 :       return target;
   10299              : 
   10300        18048 :     case WIDEN_MULT_EXPR:
   10301              :       /* If first operand is constant, swap them.
   10302              :          Thus the following special case checks need only
   10303              :          check the second operand.  */
   10304        18048 :       if (TREE_CODE (treeop0) == INTEGER_CST)
   10305          368 :         std::swap (treeop0, treeop1);
   10306              : 
   10307              :       /* First, check if we have a multiplication of one signed and one
   10308              :          unsigned operand.  */
   10309        18048 :       if (TREE_CODE (treeop1) != INTEGER_CST
   10310        18048 :           && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
   10311        13766 :               != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
   10312              :         {
   10313            0 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
   10314            0 :           this_optab = usmul_widen_optab;
   10315            0 :           if (find_widening_optab_handler (this_optab, mode, innermode)
   10316              :                 != CODE_FOR_nothing)
   10317              :             {
   10318            0 :               if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10319            0 :                 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
   10320              :                                  EXPAND_NORMAL);
   10321              :               else
   10322            0 :                 expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
   10323              :                                  EXPAND_NORMAL);
   10324              :               /* op0 and op1 might still be constant, despite the above
   10325              :                  != INTEGER_CST check.  Handle it.  */
   10326            0 :               if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10327              :                 {
   10328            0 :                   op0 = convert_modes (mode, innermode, op0, true);
   10329            0 :                   op1 = convert_modes (mode, innermode, op1, false);
   10330            0 :                   return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
   10331              :                                                         target, unsignedp));
   10332              :                 }
   10333            0 :               goto binop3;
   10334              :             }
   10335              :         }
   10336              :       /* Check for a multiplication with matching signedness.  */
   10337        18048 :       else if ((TREE_CODE (treeop1) == INTEGER_CST
   10338         4282 :                 && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
   10339        18052 :                || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
   10340        13770 :                    == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
   10341              :         {
   10342        18048 :           tree op0type = TREE_TYPE (treeop0);
   10343        18048 :           machine_mode innermode = TYPE_MODE (op0type);
   10344        18048 :           bool zextend_p = TYPE_UNSIGNED (op0type);
   10345        18048 :           optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
   10346         2550 :           this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
   10347              : 
   10348        18048 :           if (TREE_CODE (treeop0) != INTEGER_CST)
   10349              :             {
   10350        18048 :               if (find_widening_optab_handler (this_optab, mode, innermode)
   10351              :                   != CODE_FOR_nothing)
   10352              :                 {
   10353        18048 :                   expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
   10354              :                                    EXPAND_NORMAL);
   10355              :                   /* op0 and op1 might still be constant, despite the above
   10356              :                      != INTEGER_CST check.  Handle it.  */
   10357        18048 :                   if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10358              :                     {
   10359            0 :                      widen_mult_const:
   10360            0 :                       op0 = convert_modes (mode, innermode, op0, zextend_p);
   10361            0 :                       op1
   10362            0 :                         = convert_modes (mode, innermode, op1,
   10363            0 :                                          TYPE_UNSIGNED (TREE_TYPE (treeop1)));
   10364            0 :                       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
   10365              :                                                             target,
   10366              :                                                             unsignedp));
   10367              :                     }
   10368        18048 :                   temp = expand_widening_mult (mode, op0, op1, target,
   10369              :                                                unsignedp, this_optab);
   10370        18048 :                   return REDUCE_BIT_FIELD (temp);
   10371              :                 }
   10372            0 :               if (find_widening_optab_handler (other_optab, mode, innermode)
   10373              :                   != CODE_FOR_nothing
   10374            0 :                   && innermode == word_mode)
   10375              :                 {
   10376            0 :                   rtx htem, hipart;
   10377            0 :                   op0 = expand_normal (treeop0);
   10378            0 :                   op1 = expand_normal (treeop1);
   10379              :                   /* op0 and op1 might be constants, despite the above
   10380              :                      != INTEGER_CST check.  Handle it.  */
   10381            0 :                   if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10382            0 :                     goto widen_mult_const;
   10383            0 :                   temp = expand_binop (mode, other_optab, op0, op1, target,
   10384              :                                        unsignedp, OPTAB_LIB_WIDEN);
   10385            0 :                   hipart = gen_highpart (word_mode, temp);
   10386            0 :                   htem = expand_mult_highpart_adjust (word_mode, hipart,
   10387              :                                                       op0, op1, hipart,
   10388              :                                                       zextend_p);
   10389            0 :                   if (htem != hipart)
   10390            0 :                     emit_move_insn (hipart, htem);
   10391            0 :                   return REDUCE_BIT_FIELD (temp);
   10392              :                 }
   10393              :             }
   10394              :         }
   10395            0 :       treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
   10396            0 :       treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
   10397            0 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10398            0 :       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
   10399              : 
   10400      1383552 :     case MULT_EXPR:
   10401              :       /* If this is a fixed-point operation, then we cannot use the code
   10402              :          below because "expand_mult" doesn't support sat/no-sat fixed-point
   10403              :          multiplications.   */
   10404      1383552 :       if (ALL_FIXED_POINT_MODE_P (mode))
   10405            0 :         goto binop;
   10406              : 
   10407              :       /* If first operand is constant, swap them.
   10408              :          Thus the following special case checks need only
   10409              :          check the second operand.  */
   10410      1383552 :       if (TREE_CODE (treeop0) == INTEGER_CST)
   10411          686 :         std::swap (treeop0, treeop1);
   10412              : 
   10413              :       /* Attempt to return something suitable for generating an
   10414              :          indexed address, for machines that support that.  */
   10415              : 
   10416       533976 :       if (modifier == EXPAND_SUM && mode == ptr_mode
   10417      1917528 :           && tree_fits_shwi_p (treeop1))
   10418              :         {
   10419       527387 :           tree exp1 = treeop1;
   10420              : 
   10421       527387 :           op0 = expand_expr (treeop0, subtarget, VOIDmode,
   10422              :                              EXPAND_SUM);
   10423              : 
   10424       527387 :           if (!REG_P (op0))
   10425       246631 :             op0 = force_operand (op0, NULL_RTX);
   10426       527387 :           if (!REG_P (op0))
   10427         2237 :             op0 = copy_to_mode_reg (mode, op0);
   10428              : 
   10429       527387 :           op1 = gen_int_mode (tree_to_shwi (exp1),
   10430       527387 :                               TYPE_MODE (TREE_TYPE (exp1)));
   10431       527387 :           return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
   10432              :         }
   10433              : 
   10434       856165 :       if (modifier == EXPAND_STACK_PARM)
   10435         2943 :         target = 0;
   10436              : 
   10437       856165 :       if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
   10438              :         {
   10439       510234 :           gimple *def_stmt0 = get_def_for_expr (treeop0, TRUNC_DIV_EXPR);
   10440       510234 :           gimple *def_stmt1 = get_def_for_expr (treeop1, TRUNC_DIV_EXPR);
   10441       510234 :           if (def_stmt0
   10442       510234 :               && !operand_equal_p (treeop1, gimple_assign_rhs2 (def_stmt0), 0))
   10443              :             def_stmt0 = NULL;
   10444       510234 :           if (def_stmt1
   10445       510234 :               && !operand_equal_p (treeop0, gimple_assign_rhs2 (def_stmt1), 0))
   10446              :             def_stmt1 = NULL;
   10447              : 
   10448       510234 :           if (def_stmt0 || def_stmt1)
   10449              :             {
   10450              :               /* X / Y * Y can be expanded as X - X % Y too.
   10451              :                  Choose the cheaper sequence of those two.  */
   10452          252 :               if (def_stmt0)
   10453          252 :                 treeop0 = gimple_assign_rhs1 (def_stmt0);
   10454              :               else
   10455              :                 {
   10456            0 :                   treeop1 = treeop0;
   10457            0 :                   treeop0 = gimple_assign_rhs1 (def_stmt1);
   10458              :                 }
   10459          252 :               expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
   10460              :                                EXPAND_NORMAL);
   10461          252 :               bool speed_p = optimize_insn_for_speed_p ();
   10462          252 :               do_pending_stack_adjust ();
   10463          252 :               start_sequence ();
   10464          252 :               rtx divmul_ret
   10465          252 :                 = expand_expr_divmod (TRUNC_DIV_EXPR, mode, treeop0, treeop1,
   10466              :                                       op0, op1, NULL_RTX, unsignedp);
   10467          252 :               divmul_ret = expand_mult (mode, divmul_ret, op1, target,
   10468              :                                         unsignedp);
   10469          252 :               rtx_insn *divmul_insns = end_sequence ();
   10470          252 :               start_sequence ();
   10471          252 :               rtx modsub_ret
   10472          252 :                 = expand_expr_divmod (TRUNC_MOD_EXPR, mode, treeop0, treeop1,
   10473              :                                       op0, op1, NULL_RTX, unsignedp);
   10474          252 :               this_optab = optab_for_tree_code (MINUS_EXPR, type,
   10475              :                                                 optab_default);
   10476          252 :               modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
   10477              :                                          target, unsignedp, OPTAB_LIB_WIDEN);
   10478          252 :               rtx_insn *modsub_insns = end_sequence ();
   10479          252 :               unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
   10480          252 :               unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
   10481              :               /* If costs are the same then use as tie breaker the other other
   10482              :                  factor.  */
   10483          252 :               if (divmul_cost == modsub_cost)
   10484              :                 {
   10485           20 :                   divmul_cost = seq_cost (divmul_insns, !speed_p);
   10486           20 :                   modsub_cost = seq_cost (modsub_insns, !speed_p);
   10487              :                 }
   10488              : 
   10489          252 :               if (divmul_cost <= modsub_cost)
   10490              :                 {
   10491          178 :                   emit_insn (divmul_insns);
   10492          178 :                   return REDUCE_BIT_FIELD (divmul_ret);
   10493              :                 }
   10494           74 :               emit_insn (modsub_insns);
   10495           74 :               return REDUCE_BIT_FIELD (modsub_ret);
   10496              :             }
   10497              :         }
   10498              : 
   10499       855913 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10500              : 
   10501              :       /* Expand X*Y as X&-Y when Y must be zero or one.  */
   10502       855913 :       if (SCALAR_INT_MODE_P (mode))
   10503              :         {
   10504       723825 :           bool bit0_p = expr_has_boolean_range (treeop0, currently_expanding_gimple_stmt);
   10505       723825 :           bool bit1_p = expr_has_boolean_range (treeop1, currently_expanding_gimple_stmt);
   10506              : 
   10507              :           /* Expand X*Y as X&Y when both X and Y must be zero or one.  */
   10508       723825 :           if (bit0_p && bit1_p)
   10509            4 :             return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
   10510              : 
   10511       723821 :           if (bit0_p || bit1_p)
   10512              :             {
   10513         4562 :               bool speed = optimize_insn_for_speed_p ();
   10514         4562 :               int cost = add_cost (speed, mode) + neg_cost (speed, mode);
   10515         4562 :               struct algorithm algorithm;
   10516         4562 :               enum mult_variant variant;
   10517         4562 :               if (CONST_INT_P (op1)
   10518         4562 :                   ? !choose_mult_variant (mode, INTVAL (op1),
   10519              :                                           &algorithm, &variant, cost)
   10520          675 :                   : cost < mul_cost (speed, mode))
   10521              :                 {
   10522         1989 :                   temp = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
   10523              :                                               op1, target)
   10524          256 :                                 : expand_and (mode, op0,
   10525              :                                               negate_rtx (mode, op1),
   10526              :                                               target);
   10527         1989 :                   return REDUCE_BIT_FIELD (temp);
   10528              :                 }
   10529              :             }
   10530              :         }
   10531              : 
   10532       853920 :       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
   10533              : 
   10534       153315 :     case TRUNC_MOD_EXPR:
   10535       153315 :     case FLOOR_MOD_EXPR:
   10536       153315 :     case CEIL_MOD_EXPR:
   10537       153315 :     case ROUND_MOD_EXPR:
   10538              : 
   10539       153315 :     case TRUNC_DIV_EXPR:
   10540       153315 :     case FLOOR_DIV_EXPR:
   10541       153315 :     case CEIL_DIV_EXPR:
   10542       153315 :     case ROUND_DIV_EXPR:
   10543       153315 :     case EXACT_DIV_EXPR:
   10544              :       /* If this is a fixed-point operation, then we cannot use the code
   10545              :          below because "expand_divmod" doesn't support sat/no-sat fixed-point
   10546              :          divisions.   */
   10547       153315 :       if (ALL_FIXED_POINT_MODE_P (mode))
   10548            0 :         goto binop;
   10549              : 
   10550       153315 :       if (modifier == EXPAND_STACK_PARM)
   10551          330 :         target = 0;
   10552              :       /* Possible optimization: compute the dividend with EXPAND_SUM
   10553              :          then if the divisor is constant can optimize the case
   10554              :          where some terms of the dividend have coeffs divisible by it.  */
   10555       153315 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10556       153315 :       return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
   10557       153315 :                                  target, unsignedp);
   10558              : 
   10559        30690 :     case RDIV_EXPR:
   10560        30690 :       goto binop;
   10561              : 
   10562         1726 :     case MULT_HIGHPART_EXPR:
   10563         1726 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10564         1726 :       temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
   10565         1726 :       gcc_assert (temp);
   10566              :       return temp;
   10567              : 
   10568            0 :     case FIXED_CONVERT_EXPR:
   10569            0 :       op0 = expand_normal (treeop0);
   10570            0 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10571            0 :         target = gen_reg_rtx (mode);
   10572              : 
   10573            0 :       if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
   10574            0 :            && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10575            0 :           || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
   10576            0 :         expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
   10577              :       else
   10578            0 :         expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
   10579              :       return target;
   10580              : 
   10581        47803 :     case FIX_TRUNC_EXPR:
   10582        47803 :       op0 = expand_normal (treeop0);
   10583        47803 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10584         3155 :         target = gen_reg_rtx (mode);
   10585        47803 :       expand_fix (target, op0, unsignedp);
   10586        47803 :       return target;
   10587              : 
   10588       132684 :     case FLOAT_EXPR:
   10589       132684 :       op0 = expand_normal (treeop0);
   10590       132684 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10591        62611 :         target = gen_reg_rtx (mode);
   10592              :       /* expand_float can't figure out what to do if FROM has VOIDmode.
   10593              :          So give it the correct mode.  With -O, cse will optimize this.  */
   10594       132684 :       if (GET_MODE (op0) == VOIDmode)
   10595          109 :         op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
   10596              :                                 op0);
   10597       265368 :       expand_float (target, op0,
   10598       132684 :                     TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10599       132684 :       return target;
   10600              : 
   10601        49604 :     case NEGATE_EXPR:
   10602        49604 :       op0 = expand_expr (treeop0, subtarget,
   10603              :                          VOIDmode, EXPAND_NORMAL);
   10604        49604 :       if (modifier == EXPAND_STACK_PARM)
   10605          245 :         target = 0;
   10606        49604 :       temp = expand_unop (mode,
   10607              :                           optab_for_tree_code (NEGATE_EXPR, type,
   10608              :                                                optab_default),
   10609              :                           op0, target, 0);
   10610        49604 :       gcc_assert (temp);
   10611        49604 :       return REDUCE_BIT_FIELD (temp);
   10612              : 
   10613        24295 :     case ABS_EXPR:
   10614        24295 :     case ABSU_EXPR:
   10615        24295 :       op0 = expand_expr (treeop0, subtarget,
   10616              :                          VOIDmode, EXPAND_NORMAL);
   10617        24295 :       if (modifier == EXPAND_STACK_PARM)
   10618           66 :         target = 0;
   10619              : 
   10620              :       /* ABS_EXPR is not valid for complex arguments.  */
   10621        24295 :       gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
   10622              :                   && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
   10623              : 
   10624              :       /* Unsigned abs is simply the operand.  Testing here means we don't
   10625              :          risk generating incorrect code below.  */
   10626        24295 :       if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10627              :         return op0;
   10628              : 
   10629        24295 :       return expand_abs (mode, op0, target, unsignedp,
   10630        48590 :                          safe_from_p (target, treeop0, 1));
   10631              : 
   10632       111605 :     case MAX_EXPR:
   10633       111605 :     case MIN_EXPR:
   10634       111605 :       target = original_target;
   10635       111605 :       if (target == 0
   10636       111605 :           || modifier == EXPAND_STACK_PARM
   10637        58789 :           || (MEM_P (target) && MEM_VOLATILE_P (target))
   10638        58789 :           || GET_MODE (target) != mode
   10639       170394 :           || (REG_P (target)
   10640        52248 :               && REGNO (target) < FIRST_PSEUDO_REGISTER))
   10641        52816 :         target = gen_reg_rtx (mode);
   10642       111605 :       expand_operands (treeop0, treeop1,
   10643              :                        target, &op0, &op1, EXPAND_NORMAL);
   10644              : 
   10645              :       /* First try to do it with a special MIN or MAX instruction.
   10646              :          If that does not win, use a conditional jump to select the proper
   10647              :          value.  */
   10648       111605 :       this_optab = optab_for_tree_code (code, type, optab_default);
   10649       111605 :       temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
   10650              :                            OPTAB_WIDEN);
   10651       111605 :       if (temp != 0)
   10652              :         return temp;
   10653              : 
   10654          122 :       if (VECTOR_TYPE_P (type))
   10655            0 :         gcc_unreachable ();
   10656              : 
   10657              :       /* At this point, a MEM target is no longer useful; we will get better
   10658              :          code without it.  */
   10659              : 
   10660          122 :       if (! REG_P (target))
   10661            1 :         target = gen_reg_rtx (mode);
   10662              : 
   10663              :       /* If op1 was placed in target, swap op0 and op1.  */
   10664          122 :       if (target != op0 && target == op1)
   10665            0 :         std::swap (op0, op1);
   10666              : 
   10667              :       /* We generate better code and avoid problems with op1 mentioning
   10668              :          target by forcing op1 into a pseudo if it isn't a constant.  */
   10669          122 :       if (! CONSTANT_P (op1))
   10670           42 :         op1 = force_reg (mode, op1);
   10671              : 
   10672          122 :       {
   10673          122 :         enum rtx_code comparison_code;
   10674          122 :         rtx cmpop1 = op1;
   10675              : 
   10676          122 :         if (code == MAX_EXPR)
   10677           62 :           comparison_code = unsignedp ? GEU : GE;
   10678              :         else
   10679           60 :           comparison_code = unsignedp ? LEU : LE;
   10680              : 
   10681              :         /* Canonicalize to comparisons against 0.  */
   10682          122 :         if (op1 == const1_rtx)
   10683              :           {
   10684              :             /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
   10685              :                or (a != 0 ? a : 1) for unsigned.
   10686              :                For MIN we are safe converting (a <= 1 ? a : 1)
   10687              :                into (a <= 0 ? a : 1)  */
   10688            0 :             cmpop1 = const0_rtx;
   10689            0 :             if (code == MAX_EXPR)
   10690            0 :               comparison_code = unsignedp ? NE : GT;
   10691              :           }
   10692          122 :         if (op1 == constm1_rtx && !unsignedp)
   10693              :           {
   10694              :             /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
   10695              :                and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
   10696            0 :             cmpop1 = const0_rtx;
   10697            0 :             if (code == MIN_EXPR)
   10698            0 :               comparison_code = LT;
   10699              :           }
   10700              : 
   10701              :         /* Use a conditional move if possible.  */
   10702          122 :         if (can_conditionally_move_p (mode))
   10703              :           {
   10704           75 :             rtx insn;
   10705              : 
   10706           75 :             start_sequence ();
   10707              : 
   10708              :             /* Try to emit the conditional move.  */
   10709           75 :             insn = emit_conditional_move (target,
   10710              :                                           { comparison_code,
   10711              :                                             op0, cmpop1, mode },
   10712              :                                           op0, op1, mode,
   10713              :                                           unsignedp);
   10714              : 
   10715              :             /* If we could do the conditional move, emit the sequence,
   10716              :                and return.  */
   10717           75 :             if (insn)
   10718              :               {
   10719           41 :                 rtx_insn *seq = end_sequence ();
   10720           41 :                 emit_insn (seq);
   10721           41 :                 return target;
   10722              :               }
   10723              : 
   10724              :             /* Otherwise discard the sequence and fall back to code with
   10725              :                branches.  */
   10726           34 :             end_sequence ();
   10727              :           }
   10728              : 
   10729           81 :         if (target != op0)
   10730           52 :           emit_move_insn (target, op0);
   10731              : 
   10732           81 :         lab = gen_label_rtx ();
   10733           81 :         do_compare_rtx_and_jump (target, cmpop1, comparison_code,
   10734              :                                  unsignedp, mode, NULL_RTX, NULL, lab,
   10735              :                                  profile_probability::uninitialized ());
   10736              :       }
   10737           81 :       emit_move_insn (target, op1);
   10738           81 :       emit_label (lab);
   10739           81 :       return target;
   10740              : 
   10741        56684 :     case BIT_NOT_EXPR:
   10742        56684 :       op0 = expand_expr (treeop0, subtarget,
   10743              :                          VOIDmode, EXPAND_NORMAL);
   10744        56684 :       if (modifier == EXPAND_STACK_PARM)
   10745           88 :         target = 0;
   10746              :       /* In case we have to reduce the result to bitfield precision
   10747              :          for unsigned bitfield expand this as XOR with a proper constant
   10748              :          instead.  */
   10749        56684 :       if (reduce_bit_field && TYPE_UNSIGNED (type))
   10750              :         {
   10751        20686 :           int_mode = SCALAR_INT_TYPE_MODE (type);
   10752        20686 :           wide_int mask = wi::mask (TYPE_PRECISION (type),
   10753        41372 :                                     false, GET_MODE_PRECISION (int_mode));
   10754              : 
   10755        41372 :           temp = expand_binop (int_mode, xor_optab, op0,
   10756        41372 :                                immed_wide_int_const (mask, int_mode),
   10757              :                                target, 1, OPTAB_LIB_WIDEN);
   10758        20686 :         }
   10759              :       else
   10760        35998 :         temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
   10761        56684 :       gcc_assert (temp);
   10762              :       return temp;
   10763              : 
   10764              :       /* ??? Can optimize bitwise operations with one arg constant.
   10765              :          Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
   10766              :          and (a bitwise1 b) bitwise2 b (etc)
   10767              :          but that is probably not worth while.  */
   10768              : 
   10769       618897 :     case BIT_AND_EXPR:
   10770       618897 :     case BIT_IOR_EXPR:
   10771       618897 :     case BIT_XOR_EXPR:
   10772       618897 :       goto binop;
   10773              : 
   10774         7951 :     case LROTATE_EXPR:
   10775         7951 :     case RROTATE_EXPR:
   10776         7951 :       gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
   10777              :                   || type_has_mode_precision_p (type));
   10778              :       /* fall through */
   10779              : 
   10780       282495 :     case LSHIFT_EXPR:
   10781       282495 :     case RSHIFT_EXPR:
   10782       282495 :       {
   10783              :         /* If this is a fixed-point operation, then we cannot use the code
   10784              :            below because "expand_shift" doesn't support sat/no-sat fixed-point
   10785              :            shifts.  */
   10786       282495 :         if (ALL_FIXED_POINT_MODE_P (mode))
   10787            0 :           goto binop;
   10788              : 
   10789       282495 :         if (! safe_from_p (subtarget, treeop1, 1))
   10790         4752 :           subtarget = 0;
   10791       282495 :         if (modifier == EXPAND_STACK_PARM)
   10792         2565 :           target = 0;
   10793       282495 :         op0 = expand_expr (treeop0, subtarget,
   10794              :                            VOIDmode, EXPAND_NORMAL);
   10795              : 
   10796              :         /* Left shift optimization when shifting across word_size boundary.
   10797              : 
   10798              :            If mode == GET_MODE_WIDER_MODE (word_mode), then normally
   10799              :            there isn't native instruction to support this wide mode
   10800              :            left shift.  Given below scenario:
   10801              : 
   10802              :             Type A = (Type) B  << C
   10803              : 
   10804              :             |<                T          >|
   10805              :             | dest_high  |  dest_low |
   10806              : 
   10807              :                          | word_size |
   10808              : 
   10809              :            If the shift amount C caused we shift B to across the word
   10810              :            size boundary, i.e part of B shifted into high half of
   10811              :            destination register, and part of B remains in the low
   10812              :            half, then GCC will use the following left shift expand
   10813              :            logic:
   10814              : 
   10815              :            1. Initialize dest_low to B.
   10816              :            2. Initialize every bit of dest_high to the sign bit of B.
   10817              :            3. Logic left shift dest_low by C bit to finalize dest_low.
   10818              :               The value of dest_low before this shift is kept in a temp D.
   10819              :            4. Logic left shift dest_high by C.
   10820              :            5. Logic right shift D by (word_size - C).
   10821              :            6. Or the result of 4 and 5 to finalize dest_high.
   10822              : 
   10823              :            While, by checking gimple statements, if operand B is
   10824              :            coming from signed extension, then we can simplify above
   10825              :            expand logic into:
   10826              : 
   10827              :               1. dest_high = src_low >> (word_size - C).
   10828              :               2. dest_low = src_low << C.
   10829              : 
   10830              :            We can use one arithmetic right shift to finish all the
   10831              :            purpose of steps 2, 4, 5, 6, thus we reduce the steps
   10832              :            needed from 6 into 2.
   10833              : 
   10834              :            The case is similar for zero extension, except that we
   10835              :            initialize dest_high to zero rather than copies of the sign
   10836              :            bit from B.  Furthermore, we need to use a logical right shift
   10837              :            in this case.
   10838              : 
   10839              :            The choice of sign-extension versus zero-extension is
   10840              :            determined entirely by whether or not B is signed and is
   10841              :            independent of the current setting of unsignedp.  */
   10842              : 
   10843       282495 :         temp = NULL_RTX;
   10844       282495 :         if (code == LSHIFT_EXPR
   10845       282495 :             && target
   10846        32257 :             && REG_P (target)
   10847       311891 :             && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
   10848        29463 :             && mode == int_mode
   10849         1503 :             && TREE_CONSTANT (treeop1)
   10850       283332 :             && TREE_CODE (treeop0) == SSA_NAME)
   10851              :           {
   10852          837 :             gimple *def = SSA_NAME_DEF_STMT (treeop0);
   10853          837 :             if (is_gimple_assign (def)
   10854          837 :                 && gimple_assign_rhs_code (def) == NOP_EXPR)
   10855              :               {
   10856          324 :                 scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
   10857              :                   (TREE_TYPE (gimple_assign_rhs1 (def)));
   10858              : 
   10859          648 :                 if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
   10860          602 :                     && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
   10861          466 :                     && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
   10862           71 :                         >= GET_MODE_BITSIZE (word_mode)))
   10863              :                   {
   10864           67 :                     rtx_insn *seq, *seq_old;
   10865           67 :                     poly_uint64 high_off = subreg_highpart_offset (word_mode,
   10866              :                                                                    int_mode);
   10867           67 :                     bool extend_unsigned
   10868           67 :                       = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
   10869           67 :                     rtx low = lowpart_subreg (word_mode, op0, int_mode);
   10870           67 :                     rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
   10871           67 :                     rtx dest_high = simplify_gen_subreg (word_mode, target,
   10872              :                                                          int_mode, high_off);
   10873           67 :                     HOST_WIDE_INT ramount = (BITS_PER_WORD
   10874           67 :                                              - TREE_INT_CST_LOW (treeop1));
   10875           67 :                     tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
   10876              : 
   10877           67 :                     start_sequence ();
   10878              :                     /* dest_high = src_low >> (word_size - C).  */
   10879           67 :                     temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
   10880              :                                                   rshift, dest_high,
   10881              :                                                   extend_unsigned);
   10882           67 :                     if (temp != dest_high)
   10883            0 :                       emit_move_insn (dest_high, temp);
   10884              : 
   10885              :                     /* dest_low = src_low << C.  */
   10886           67 :                     temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
   10887              :                                                   treeop1, dest_low, unsignedp);
   10888           67 :                     if (temp != dest_low)
   10889            2 :                       emit_move_insn (dest_low, temp);
   10890              : 
   10891           67 :                     seq = end_sequence ();
   10892           67 :                     temp = target ;
   10893              : 
   10894           67 :                     if (have_insn_for (ASHIFT, int_mode))
   10895              :                       {
   10896           67 :                         bool speed_p = optimize_insn_for_speed_p ();
   10897           67 :                         start_sequence ();
   10898           67 :                         rtx ret_old = expand_variable_shift (code, int_mode,
   10899              :                                                              op0, treeop1,
   10900              :                                                              target,
   10901              :                                                              unsignedp);
   10902              : 
   10903           67 :                         seq_old = end_sequence ();
   10904          134 :                         if (seq_cost (seq, speed_p)
   10905           67 :                             >= seq_cost (seq_old, speed_p))
   10906              :                           {
   10907           67 :                             seq = seq_old;
   10908           67 :                             temp = ret_old;
   10909              :                           }
   10910              :                       }
   10911           67 :                       emit_insn (seq);
   10912              :                   }
   10913              :               }
   10914              :           }
   10915              : 
   10916           67 :         if (temp == NULL_RTX)
   10917       282428 :           temp = expand_variable_shift (code, mode, op0, treeop1, target,
   10918              :                                         unsignedp);
   10919       282495 :         if (code == LSHIFT_EXPR)
   10920        78382 :           temp = REDUCE_BIT_FIELD (temp);
   10921              :         return temp;
   10922              :       }
   10923              : 
   10924              :       /* Could determine the answer when only additive constants differ.  Also,
   10925              :          the addition of one can be handled by changing the condition.  */
   10926       588951 :     case LT_EXPR:
   10927       588951 :     case LE_EXPR:
   10928       588951 :     case GT_EXPR:
   10929       588951 :     case GE_EXPR:
   10930       588951 :     case EQ_EXPR:
   10931       588951 :     case NE_EXPR:
   10932       588951 :     case UNORDERED_EXPR:
   10933       588951 :     case ORDERED_EXPR:
   10934       588951 :     case UNLT_EXPR:
   10935       588951 :     case UNLE_EXPR:
   10936       588951 :     case UNGT_EXPR:
   10937       588951 :     case UNGE_EXPR:
   10938       588951 :     case UNEQ_EXPR:
   10939       588951 :     case LTGT_EXPR:
   10940       588951 :       {
   10941       956208 :         temp = do_store_flag (ops,
   10942              :                               modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
   10943              :                               tmode != VOIDmode ? tmode : mode);
   10944       588951 :         if (temp)
   10945              :           return temp;
   10946              : 
   10947              :         /* Use a compare and a jump for BLKmode comparisons, or for function
   10948              :            type comparisons is have_canonicalize_funcptr_for_compare.  */
   10949              : 
   10950            0 :         if ((target == 0
   10951            0 :              || modifier == EXPAND_STACK_PARM
   10952            0 :              || ! safe_from_p (target, treeop0, 1)
   10953            0 :              || ! safe_from_p (target, treeop1, 1)
   10954              :              /* Make sure we don't have a hard reg (such as function's return
   10955              :                 value) live across basic blocks, if not optimizing.  */
   10956            0 :              || (!optimize && REG_P (target)
   10957            0 :                  && REGNO (target) < FIRST_PSEUDO_REGISTER)))
   10958            0 :           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
   10959              : 
   10960            0 :         emit_move_insn (target, const0_rtx);
   10961              : 
   10962            0 :         rtx_code_label *lab1 = gen_label_rtx ();
   10963            0 :         jumpifnot_1 (code, treeop0, treeop1, lab1,
   10964              :                      profile_probability::uninitialized ());
   10965              : 
   10966            0 :         if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
   10967            0 :           emit_move_insn (target, constm1_rtx);
   10968              :         else
   10969            0 :           emit_move_insn (target, const1_rtx);
   10970              : 
   10971            0 :         emit_label (lab1);
   10972            0 :         return target;
   10973              :       }
   10974        54557 :     case COMPLEX_EXPR:
   10975              :       /* Get the rtx code of the operands.  */
   10976        54557 :       op0 = expand_normal (treeop0);
   10977        54557 :       op1 = expand_normal (treeop1);
   10978              : 
   10979        54557 :       if (!target)
   10980         2736 :         target = gen_reg_rtx (TYPE_MODE (type));
   10981              :       else
   10982              :         /* If target overlaps with op1, then either we need to force
   10983              :            op1 into a pseudo (if target also overlaps with op0),
   10984              :            or write the complex parts in reverse order.  */
   10985        51821 :         switch (GET_CODE (target))
   10986              :           {
   10987        49067 :           case CONCAT:
   10988        49067 :             if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
   10989              :               {
   10990            0 :                 if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
   10991              :                   {
   10992            0 :                   complex_expr_force_op1:
   10993         1724 :                     temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
   10994          862 :                     emit_move_insn (temp, op1);
   10995          862 :                     op1 = temp;
   10996          862 :                     break;
   10997              :                   }
   10998            0 :               complex_expr_swap_order:
   10999              :                 /* Move the imaginary (op1) and real (op0) parts to their
   11000              :                    location.  */
   11001            1 :                 write_complex_part (target, op1, true, true);
   11002            1 :                 write_complex_part (target, op0, false, false);
   11003              : 
   11004            1 :                 return target;
   11005              :               }
   11006              :             break;
   11007         2754 :           case MEM:
   11008         5508 :             temp = adjust_address_nv (target,
   11009              :                                       GET_MODE_INNER (GET_MODE (target)), 0);
   11010         2754 :             if (reg_overlap_mentioned_p (temp, op1))
   11011              :               {
   11012          863 :                 scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
   11013         1726 :                 temp = adjust_address_nv (target, imode,
   11014              :                                           GET_MODE_SIZE (imode));
   11015          863 :                 if (reg_overlap_mentioned_p (temp, op0))
   11016          862 :                   goto complex_expr_force_op1;
   11017            1 :                 goto complex_expr_swap_order;
   11018              :               }
   11019              :             break;
   11020            0 :           default:
   11021            0 :             if (reg_overlap_mentioned_p (target, op1))
   11022              :               {
   11023            0 :                 if (reg_overlap_mentioned_p (target, op0))
   11024            0 :                   goto complex_expr_force_op1;
   11025            0 :                 goto complex_expr_swap_order;
   11026              :               }
   11027              :             break;
   11028              :           }
   11029              : 
   11030              :       /* Move the real (op0) and imaginary (op1) parts to their location.  */
   11031        54556 :       write_complex_part (target, op0, false, true);
   11032        54556 :       write_complex_part (target, op1, true, false);
   11033              : 
   11034        54556 :       return target;
   11035              : 
   11036            0 :     case WIDEN_SUM_EXPR:
   11037            0 :       {
   11038            0 :         tree oprnd0 = treeop0;
   11039            0 :         tree oprnd1 = treeop1;
   11040              : 
   11041            0 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11042            0 :         target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
   11043              :                                             target, unsignedp);
   11044            0 :         return target;
   11045              :       }
   11046              : 
   11047        17380 :     case VEC_UNPACK_HI_EXPR:
   11048        17380 :     case VEC_UNPACK_LO_EXPR:
   11049        17380 :     case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
   11050        17380 :     case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
   11051        17380 :       {
   11052        17380 :         op0 = expand_normal (treeop0);
   11053        17380 :         temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
   11054              :                                           target, unsignedp);
   11055        17380 :         gcc_assert (temp);
   11056              :         return temp;
   11057              :       }
   11058              : 
   11059         1724 :     case VEC_UNPACK_FLOAT_HI_EXPR:
   11060         1724 :     case VEC_UNPACK_FLOAT_LO_EXPR:
   11061         1724 :       {
   11062         1724 :         op0 = expand_normal (treeop0);
   11063              :         /* The signedness is determined from input operand.  */
   11064         1724 :         temp = expand_widen_pattern_expr
   11065         3448 :           (ops, op0, NULL_RTX, NULL_RTX,
   11066         1724 :            target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   11067              : 
   11068         1724 :         gcc_assert (temp);
   11069              :         return temp;
   11070              :       }
   11071              : 
   11072         1011 :     case VEC_WIDEN_MULT_HI_EXPR:
   11073         1011 :     case VEC_WIDEN_MULT_LO_EXPR:
   11074         1011 :     case VEC_WIDEN_MULT_EVEN_EXPR:
   11075         1011 :     case VEC_WIDEN_MULT_ODD_EXPR:
   11076         1011 :     case VEC_WIDEN_LSHIFT_HI_EXPR:
   11077         1011 :     case VEC_WIDEN_LSHIFT_LO_EXPR:
   11078         1011 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11079         1011 :       target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
   11080              :                                           target, unsignedp);
   11081         1011 :       gcc_assert (target);
   11082              :       return target;
   11083              : 
   11084          340 :     case VEC_PACK_SAT_EXPR:
   11085          340 :     case VEC_PACK_FIX_TRUNC_EXPR:
   11086          340 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11087          340 :       subtarget = NULL_RTX;
   11088          340 :       goto binop;
   11089              : 
   11090        11002 :     case VEC_PACK_TRUNC_EXPR:
   11091        11002 :       if (VECTOR_BOOLEAN_TYPE_P (type)
   11092         2531 :           && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
   11093         2531 :           && mode == TYPE_MODE (TREE_TYPE (treeop0))
   11094        11706 :           && SCALAR_INT_MODE_P (mode))
   11095              :         {
   11096          704 :           class expand_operand eops[4];
   11097          704 :           machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
   11098          704 :           expand_operands (treeop0, treeop1,
   11099              :                            subtarget, &op0, &op1, EXPAND_NORMAL);
   11100          704 :           this_optab = vec_pack_sbool_trunc_optab;
   11101          704 :           enum insn_code icode = optab_handler (this_optab, imode);
   11102          704 :           create_output_operand (&eops[0], target, mode);
   11103          704 :           create_convert_operand_from (&eops[1], op0, imode, false);
   11104          704 :           create_convert_operand_from (&eops[2], op1, imode, false);
   11105          704 :           temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
   11106          704 :           create_input_operand (&eops[3], temp, imode);
   11107          704 :           expand_insn (icode, 4, eops);
   11108          704 :           return eops[0].value;
   11109              :         }
   11110        10298 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11111        10298 :       subtarget = NULL_RTX;
   11112        10298 :       goto binop;
   11113              : 
   11114           27 :     case VEC_PACK_FLOAT_EXPR:
   11115           27 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11116           27 :       expand_operands (treeop0, treeop1,
   11117              :                        subtarget, &op0, &op1, EXPAND_NORMAL);
   11118           27 :       this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
   11119              :                                         optab_default);
   11120           81 :       target = expand_binop (mode, this_optab, op0, op1, target,
   11121           27 :                              TYPE_UNSIGNED (TREE_TYPE (treeop0)),
   11122              :                              OPTAB_LIB_WIDEN);
   11123           27 :       gcc_assert (target);
   11124              :       return target;
   11125              : 
   11126        74536 :     case VEC_PERM_EXPR:
   11127        74536 :       {
   11128        74536 :         expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL);
   11129        74536 :         vec_perm_builder sel;
   11130        74536 :         if (TREE_CODE (treeop2) == VECTOR_CST
   11131        74536 :             && tree_to_vec_perm_builder (&sel, treeop2))
   11132              :           {
   11133        74526 :             machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
   11134        74526 :             temp = expand_vec_perm_const (mode, op0, op1, sel,
   11135              :                                           sel_mode, target);
   11136              :           }
   11137              :         else
   11138              :           {
   11139           10 :             op2 = expand_normal (treeop2);
   11140           10 :             temp = expand_vec_perm_var (mode, op0, op1, op2, target);
   11141              :           }
   11142        74536 :         gcc_assert (temp);
   11143        74536 :         return temp;
   11144        74536 :       }
   11145              : 
   11146          395 :     case DOT_PROD_EXPR:
   11147          395 :       {
   11148          395 :         tree oprnd0 = treeop0;
   11149          395 :         tree oprnd1 = treeop1;
   11150          395 :         tree oprnd2 = treeop2;
   11151              : 
   11152          395 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11153          395 :         op2 = expand_normal (oprnd2);
   11154          395 :         target = expand_widen_pattern_expr (ops, op0, op1, op2,
   11155              :                                             target, unsignedp);
   11156          395 :         return target;
   11157              :       }
   11158              : 
   11159          114 :       case SAD_EXPR:
   11160          114 :       {
   11161          114 :         tree oprnd0 = treeop0;
   11162          114 :         tree oprnd1 = treeop1;
   11163          114 :         tree oprnd2 = treeop2;
   11164              : 
   11165          114 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11166          114 :         op2 = expand_normal (oprnd2);
   11167          114 :         target = expand_widen_pattern_expr (ops, op0, op1, op2,
   11168              :                                             target, unsignedp);
   11169          114 :         return target;
   11170              :       }
   11171              : 
   11172            0 :     case REALIGN_LOAD_EXPR:
   11173            0 :       {
   11174            0 :         tree oprnd0 = treeop0;
   11175            0 :         tree oprnd1 = treeop1;
   11176            0 :         tree oprnd2 = treeop2;
   11177              : 
   11178            0 :         this_optab = optab_for_tree_code (code, type, optab_default);
   11179            0 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11180            0 :         op2 = expand_normal (oprnd2);
   11181            0 :         temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
   11182              :                                   target, unsignedp);
   11183            0 :         gcc_assert (temp);
   11184              :         return temp;
   11185              :       }
   11186              : 
   11187        17867 :     case COND_EXPR:
   11188        17867 :       {
   11189              :         /* A COND_EXPR with its type being VOID_TYPE represents a
   11190              :            conditional jump and is handled in
   11191              :            expand_gimple_cond_expr.  */
   11192        17867 :         gcc_assert (!VOID_TYPE_P (type));
   11193              : 
   11194              :         /* Note that COND_EXPRs whose type is a structure or union
   11195              :            are required to be constructed to contain assignments of
   11196              :            a temporary variable, so that we can evaluate them here
   11197              :            for side effect only.  If type is void, we must do likewise.  */
   11198              : 
   11199        17867 :         gcc_assert (!TREE_ADDRESSABLE (type)
   11200              :                     && !ignore
   11201              :                     && TREE_TYPE (treeop1) != void_type_node
   11202              :                     && TREE_TYPE (treeop2) != void_type_node);
   11203              : 
   11204        17867 :         temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
   11205        17867 :         if (temp)
   11206              :           return temp;
   11207              : 
   11208              :         /* If we are not to produce a result, we have no target.  Otherwise,
   11209              :            if a target was specified use it; it will not be used as an
   11210              :            intermediate target unless it is safe.  If no target, use a
   11211              :            temporary.  */
   11212              : 
   11213         3766 :         if (modifier != EXPAND_STACK_PARM
   11214         3766 :             && original_target
   11215         2189 :             && safe_from_p (original_target, treeop0, 1)
   11216            0 :             && GET_MODE (original_target) == mode
   11217         3766 :             && !MEM_P (original_target))
   11218              :           temp = original_target;
   11219              :         else
   11220         3766 :           temp = assign_temp (type, 0, 1);
   11221              : 
   11222         3766 :         do_pending_stack_adjust ();
   11223         3766 :         NO_DEFER_POP;
   11224         3766 :         rtx_code_label *lab0 = gen_label_rtx ();
   11225         3766 :         rtx_code_label *lab1 = gen_label_rtx ();
   11226         3766 :         jumpifnot (treeop0, lab0,
   11227              :                    profile_probability::uninitialized ());
   11228         3766 :         store_expr (treeop1, temp,
   11229              :                     modifier == EXPAND_STACK_PARM,
   11230              :                     false, false);
   11231              : 
   11232         3766 :         emit_jump_insn (targetm.gen_jump (lab1));
   11233         3766 :         emit_barrier ();
   11234         3766 :         emit_label (lab0);
   11235         3766 :         store_expr (treeop2, temp,
   11236              :                     modifier == EXPAND_STACK_PARM,
   11237              :                     false, false);
   11238              : 
   11239         3766 :         emit_label (lab1);
   11240         3766 :         OK_DEFER_POP;
   11241         3766 :         return temp;
   11242              :       }
   11243              : 
   11244            0 :     case VEC_DUPLICATE_EXPR:
   11245            0 :       op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
   11246            0 :       target = expand_vector_broadcast (mode, op0);
   11247            0 :       gcc_assert (target);
   11248              :       return target;
   11249              : 
   11250            0 :     case VEC_SERIES_EXPR:
   11251            0 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
   11252            0 :       return expand_vec_series_expr (mode, op0, op1, target);
   11253              : 
   11254         1000 :     case BIT_INSERT_EXPR:
   11255         1000 :       {
   11256         1000 :         unsigned bitpos = tree_to_uhwi (treeop2);
   11257         1000 :         unsigned bitsize;
   11258         1000 :         if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
   11259          656 :           bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
   11260              :         else
   11261          344 :           bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
   11262         1000 :         op0 = expand_normal (treeop0);
   11263         1000 :         op1 = expand_normal (treeop1);
   11264         1000 :         rtx dst = gen_reg_rtx (mode);
   11265         1000 :         emit_move_insn (dst, op0);
   11266         1000 :         store_bit_field (dst, bitsize, bitpos, 0, 0,
   11267         1000 :                          TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
   11268         1000 :         return dst;
   11269              :       }
   11270              : 
   11271            0 :     default:
   11272            0 :       gcc_unreachable ();
   11273              :     }
   11274              : 
   11275              :   /* Here to do an ordinary binary operator.  */
   11276      1174767 :  binop:
   11277      1174767 :   expand_operands (treeop0, treeop1,
   11278              :                    subtarget, &op0, &op1, EXPAND_NORMAL);
   11279      5621189 :  binop2:
   11280      5621189 :   this_optab = optab_for_tree_code (code, type, optab_default);
   11281      5621189 :  binop3:
   11282      5621189 :   if (modifier == EXPAND_STACK_PARM)
   11283        26617 :     target = 0;
   11284      5621189 :   temp = expand_binop (mode, this_optab, op0, op1, target,
   11285              :                        unsignedp, OPTAB_LIB_WIDEN);
   11286      5621189 :   gcc_assert (temp);
   11287              :   /* Bitwise operations do not need bitfield reduction as we expect their
   11288              :      operands being properly truncated.  */
   11289      5621189 :   if (code == BIT_XOR_EXPR
   11290              :       || code == BIT_AND_EXPR
   11291      5621189 :       || code == BIT_IOR_EXPR)
   11292              :     return temp;
   11293      5002292 :   return REDUCE_BIT_FIELD (temp);
   11294              : }
   11295              : #undef REDUCE_BIT_FIELD
   11296              : 
   11297              : 
   11298              : /* Return TRUE if expression STMT is suitable for replacement.
   11299              :    Never consider memory loads as replaceable, because those don't ever lead
   11300              :    into constant expressions.  */
   11301              : 
   11302              : static bool
   11303            8 : stmt_is_replaceable_p (gimple *stmt)
   11304              : {
   11305            8 :   if (ssa_is_replaceable_p (stmt))
   11306              :     {
   11307              :       /* Don't move around loads.  */
   11308            7 :       if (!gimple_assign_single_p (stmt)
   11309            7 :           || is_gimple_val (gimple_assign_rhs1 (stmt)))
   11310            6 :         return true;
   11311              :     }
   11312              :   return false;
   11313              : }
   11314              : 
   11315              : /* A subroutine of expand_expr_real_1.  Expand gimple assignment G,
   11316              :    which is known to set an SSA_NAME result.  The other arguments are
   11317              :    as for expand_expr_real_1.  */
   11318              : 
   11319              : rtx
   11320     14697853 : expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
   11321              :                           enum expand_modifier modifier, rtx *alt_rtl,
   11322              :                           bool inner_reference_p)
   11323              : {
   11324     14697853 :   separate_ops ops;
   11325     14697853 :   rtx r;
   11326     14697853 :   location_t saved_loc = curr_insn_location ();
   11327     14697853 :   auto loc = gimple_location (g);
   11328     14697853 :   if (loc != UNKNOWN_LOCATION)
   11329     11762149 :     set_curr_insn_location (loc);
   11330     14697853 :   tree lhs = gimple_assign_lhs (g);
   11331     14697853 :   ops.code = gimple_assign_rhs_code (g);
   11332     14697853 :   ops.type = TREE_TYPE (lhs);
   11333     14697853 :   switch (get_gimple_rhs_class (ops.code))
   11334              :     {
   11335        93787 :     case GIMPLE_TERNARY_RHS:
   11336       187574 :       ops.op2 = gimple_assign_rhs3 (g);
   11337              :       /* Fallthru */
   11338      7905910 :     case GIMPLE_BINARY_RHS:
   11339      7905910 :       ops.op1 = gimple_assign_rhs2 (g);
   11340              : 
   11341              :       /* Try to expand conditonal compare.  */
   11342      7905910 :       if (targetm.have_ccmp ())
   11343              :         {
   11344       164952 :           gcc_checking_assert (targetm.gen_ccmp_next != NULL);
   11345       164952 :           r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
   11346       164952 :           if (r)
   11347              :             break;
   11348              :         }
   11349              :       /* Fallthru */
   11350     11350893 :     case GIMPLE_UNARY_RHS:
   11351     11350893 :       ops.op0 = gimple_assign_rhs1 (g);
   11352     11350893 :       ops.location = loc;
   11353     11350893 :       r = expand_expr_real_2 (&ops, target, tmode, modifier);
   11354     11350893 :       break;
   11355      3346942 :     case GIMPLE_SINGLE_RHS:
   11356      3346942 :       {
   11357      3346942 :         r = expand_expr_real (gimple_assign_rhs1 (g), target,
   11358              :                               tmode, modifier, alt_rtl,
   11359              :                               inner_reference_p);
   11360      3346942 :         break;
   11361              :       }
   11362            0 :     default:
   11363            0 :       gcc_unreachable ();
   11364              :     }
   11365     14697853 :   set_curr_insn_location (saved_loc);
   11366     14697853 :   if (REG_P (r) && !REG_EXPR (r))
   11367      3823157 :     set_reg_attrs_for_decl_rtl (lhs, r);
   11368     14697853 :   return r;
   11369              : }
   11370              : 
   11371              : rtx
   11372    154528264 : expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
   11373              :                     enum expand_modifier modifier, rtx *alt_rtl,
   11374              :                     bool inner_reference_p)
   11375              : {
   11376    154528264 :   rtx op0, op1, temp, decl_rtl;
   11377    154528264 :   tree type;
   11378    154528264 :   int unsignedp;
   11379    154528264 :   machine_mode mode, dmode;
   11380    154528264 :   enum tree_code code = TREE_CODE (exp);
   11381    154528264 :   rtx subtarget, original_target;
   11382    154528264 :   int ignore;
   11383    154528264 :   bool reduce_bit_field;
   11384    154528264 :   location_t loc = EXPR_LOCATION (exp);
   11385    154528264 :   struct separate_ops ops;
   11386    154528264 :   tree treeop0, treeop1, treeop2;
   11387    154528264 :   tree ssa_name = NULL_TREE;
   11388    154528264 :   gimple *g;
   11389              : 
   11390              :   /* Some ABIs define padding bits in _BitInt uninitialized.  Normally, RTL
   11391              :      expansion sign/zero extends integral types with less than mode precision
   11392              :      when reading from bit-fields and after arithmetic operations (see
   11393              :      REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
   11394              :      on those extensions to have been already performed, but because of the
   11395              :      above for _BitInt they need to be sign/zero extended when reading from
   11396              :      locations that could be exposed to ABI boundaries (when loading from
   11397              :      objects in memory, or function arguments, return value).  Because we
   11398              :      internally extend after arithmetic operations, we can avoid doing that
   11399              :      when reading from SSA_NAMEs of vars.  */
   11400              : #define EXTEND_BITINT(expr) \
   11401              :   ((TREE_CODE (type) == BITINT_TYPE                                     \
   11402              :     && !bitint_extended                                                 \
   11403              :     && reduce_bit_field                                                 \
   11404              :     && mode != BLKmode                                                  \
   11405              :     && modifier != EXPAND_MEMORY                                        \
   11406              :     && modifier != EXPAND_WRITE                                         \
   11407              :     && modifier != EXPAND_INITIALIZER                                   \
   11408              :     && modifier != EXPAND_CONST_ADDRESS)                                \
   11409              :    ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
   11410              : 
   11411    154528264 :   type = TREE_TYPE (exp);
   11412    154528264 :   mode = TYPE_MODE (type);
   11413    154528264 :   unsignedp = TYPE_UNSIGNED (type);
   11414    154528264 :   if (TREE_CODE (type) == BITINT_TYPE && bitint_extended == -1)
   11415              :     {
   11416         8585 :       struct bitint_info info;
   11417         8585 :       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
   11418         8585 :       gcc_assert (ok);
   11419         8585 :       bitint_extended = info.extended;
   11420              :     }
   11421              : 
   11422    154528264 :   treeop0 = treeop1 = treeop2 = NULL_TREE;
   11423    154528264 :   if (!VL_EXP_CLASS_P (exp))
   11424    147931378 :     switch (TREE_CODE_LENGTH (code))
   11425              :       {
   11426      5447582 :         default:
   11427      5447582 :         case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
   11428     13276558 :         case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
   11429     27405629 :         case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
   11430              :         case 0: break;
   11431              :       }
   11432    154528264 :   ops.code = code;
   11433    154528264 :   ops.type = type;
   11434    154528264 :   ops.op0 = treeop0;
   11435    154528264 :   ops.op1 = treeop1;
   11436    154528264 :   ops.op2 = treeop2;
   11437    154528264 :   ops.location = loc;
   11438              : 
   11439    309056528 :   ignore = (target == const0_rtx
   11440    154528264 :             || ((CONVERT_EXPR_CODE_P (code)
   11441    149594137 :                  || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
   11442       939598 :                 && TREE_CODE (type) == VOID_TYPE));
   11443              : 
   11444              :   /* An operation in what may be a bit-field type needs the
   11445              :      result to be reduced to the precision of the bit-field type,
   11446              :      which is narrower than that of the type's mode.  */
   11447    309056305 :   reduce_bit_field = (!ignore
   11448    150198996 :                       && INTEGRAL_TYPE_P (type)
   11449     78999471 :                       && !type_has_mode_precision_p (type));
   11450              : 
   11451              :   /* If we are going to ignore this result, we need only do something
   11452              :      if there is a side-effect somewhere in the expression.  If there
   11453              :      is, short-circuit the most common cases here.  Note that we must
   11454              :      not call expand_expr with anything but const0_rtx in case this
   11455              :      is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  */
   11456              : 
   11457      4329268 :   if (ignore)
   11458              :     {
   11459      4329268 :       if (! TREE_SIDE_EFFECTS (exp))
   11460              :         return const0_rtx;
   11461              : 
   11462              :       /* Ensure we reference a volatile object even if value is ignored, but
   11463              :          don't do this if all we are doing is taking its address.  */
   11464      4329045 :       if (TREE_THIS_VOLATILE (exp)
   11465            0 :           && TREE_CODE (exp) != FUNCTION_DECL
   11466            0 :           && mode != VOIDmode && mode != BLKmode
   11467            0 :           && modifier != EXPAND_CONST_ADDRESS)
   11468              :         {
   11469            0 :           temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
   11470            0 :           if (MEM_P (temp))
   11471            0 :             copy_to_reg (temp);
   11472            0 :           return const0_rtx;
   11473              :         }
   11474              : 
   11475      4329045 :       if (TREE_CODE_CLASS (code) == tcc_unary
   11476              :           || code == BIT_FIELD_REF
   11477      4329045 :           || code == COMPONENT_REF
   11478      4329045 :           || code == INDIRECT_REF)
   11479            0 :         return expand_expr (treeop0, const0_rtx, VOIDmode,
   11480            0 :                             modifier);
   11481              : 
   11482      4329045 :       else if (TREE_CODE_CLASS (code) == tcc_binary
   11483      4329045 :                || TREE_CODE_CLASS (code) == tcc_comparison
   11484      4329045 :                || code == ARRAY_REF || code == ARRAY_RANGE_REF)
   11485              :         {
   11486            0 :           expand_expr (treeop0, const0_rtx, VOIDmode, modifier);
   11487            0 :           expand_expr (treeop1, const0_rtx, VOIDmode, modifier);
   11488            0 :           return const0_rtx;
   11489              :         }
   11490              : 
   11491              :       target = 0;
   11492              :     }
   11493              : 
   11494    154528041 :   if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
   11495        38033 :     target = 0;
   11496              : 
   11497              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
   11498    154528041 :   subtarget = get_subtarget (target);
   11499    154528041 :   original_target = target;
   11500              : 
   11501    154528041 :   switch (code)
   11502              :     {
   11503        10816 :     case LABEL_DECL:
   11504        10816 :       {
   11505        10816 :         tree function = decl_function_context (exp);
   11506              : 
   11507        10816 :         temp = label_rtx (exp);
   11508        14760 :         temp = gen_rtx_LABEL_REF (Pmode, temp);
   11509              : 
   11510        10816 :         if (function != current_function_decl
   11511         1270 :             && function != 0)
   11512         1270 :           LABEL_REF_NONLOCAL_P (temp) = 1;
   11513              : 
   11514        10816 :         temp = gen_rtx_MEM (FUNCTION_MODE, temp);
   11515        10816 :         return temp;
   11516              :       }
   11517              : 
   11518     55872348 :     case SSA_NAME:
   11519              :       /* ??? ivopts calls expander, without any preparation from
   11520              :          out-of-ssa.  So fake instructions as if this was an access to the
   11521              :          base variable.  This unnecessarily allocates a pseudo, see how we can
   11522              :          reuse it, if partition base vars have it set already.  */
   11523     55872348 :       if (!currently_expanding_to_rtl)
   11524              :         {
   11525            0 :           tree var = SSA_NAME_VAR (exp);
   11526            0 :           if (var && DECL_RTL_SET_P (var))
   11527            0 :             return DECL_RTL (var);
   11528            0 :           return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
   11529            0 :                               LAST_VIRTUAL_REGISTER + 1);
   11530              :         }
   11531              : 
   11532     55872348 :       g = get_gimple_for_ssa_name (exp);
   11533              :       /* For EXPAND_INITIALIZER try harder to get something simpler.  */
   11534     55872348 :       if (g == NULL
   11535     55872348 :           && modifier == EXPAND_INITIALIZER
   11536           26 :           && !SSA_NAME_IS_DEFAULT_DEF (exp)
   11537           11 :           && (optimize || !SSA_NAME_VAR (exp)
   11538            1 :               || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
   11539           10 :           && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
   11540     55872356 :           && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
   11541            6 :         g = SSA_NAME_DEF_STMT (exp);
   11542     55872348 :       if (safe_is_a <gassign *> (g))
   11543      8832215 :         return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
   11544      8832215 :                                          modifier, alt_rtl, inner_reference_p);
   11545     47040133 :       else if (safe_is_a <gcall *> (g))
   11546              :         {
   11547              :           /* ???  internal call expansion doesn't follow the usual API
   11548              :              of returning the destination RTX and being passed a desired
   11549              :              target.  */
   11550        73676 :           if (modifier == EXPAND_WRITE)
   11551        36842 :             return DECL_RTL (SSA_NAME_VAR (exp));
   11552        36834 :           rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
   11553        36834 :           tree tmplhs = make_tree (TREE_TYPE (exp), dest);
   11554        36834 :           tree var_or_id = SSA_NAME_VAR (exp);
   11555              :           if (!var_or_id)
   11556        26868 :             var_or_id = SSA_NAME_IDENTIFIER (exp);
   11557        36834 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, tmplhs);
   11558        36834 :           expand_internal_call (as_a <gcall *> (g));
   11559        36834 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, var_or_id);
   11560        36834 :           return dest;
   11561              :         }
   11562              : 
   11563     46966457 :       ssa_name = exp;
   11564     46966457 :       decl_rtl = get_rtx_for_ssa_name (ssa_name);
   11565     46966457 :       exp = SSA_NAME_VAR (ssa_name);
   11566              :       /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
   11567              :          SSA_NAME computed within the current function.  In such case the
   11568              :          value have been already extended before.  While if it is a function
   11569              :          parameter, result or some memory location, we need to be prepared
   11570              :          for some other compiler leaving the bits uninitialized.  */
   11571     18518289 :       if (!exp || VAR_P (exp))
   11572              :         reduce_bit_field = false;
   11573     46966457 :       goto expand_decl_rtl;
   11574              : 
   11575     19379302 :     case VAR_DECL:
   11576              :       /* Allow accel compiler to handle variables that require special
   11577              :          treatment, e.g. if they have been modified in some way earlier in
   11578              :          compilation by the adjust_private_decl OpenACC hook.  */
   11579     19379302 :       if (flag_openacc && targetm.goacc.expand_var_decl)
   11580              :         {
   11581            0 :           temp = targetm.goacc.expand_var_decl (exp);
   11582            0 :           if (temp)
   11583              :             return temp;
   11584              :         }
   11585              :       /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
   11586              :          have scalar integer modes to a reg via store_constructor.  */
   11587     19379302 :       if (TREE_READONLY (exp)
   11588      3352501 :           && !TREE_SIDE_EFFECTS (exp)
   11589      3330093 :           && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
   11590        17008 :           && immediate_const_ctor_p (DECL_INITIAL (exp))
   11591          160 :           && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
   11592          124 :           && crtl->emit.regno_pointer_align_length
   11593     19379426 :           && !target)
   11594              :         {
   11595           85 :           target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
   11596           85 :           store_constructor (DECL_INITIAL (exp), target, 0,
   11597           85 :                              int_expr_size (DECL_INITIAL (exp)), false);
   11598           85 :           return target;
   11599              :         }
   11600              :       /* ... fall through ...  */
   11601              : 
   11602     19912191 :     case PARM_DECL:
   11603              :       /* If a static var's type was incomplete when the decl was written,
   11604              :          but the type is complete now, lay out the decl now.  */
   11605     19912191 :       if (DECL_SIZE (exp) == 0
   11606        44355 :           && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
   11607     19956434 :           && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
   11608        44243 :         layout_decl (exp, 0);
   11609              : 
   11610              :       /* fall through */
   11611              : 
   11612     21364633 :     case FUNCTION_DECL:
   11613     21364633 :     case RESULT_DECL:
   11614     21364633 :       decl_rtl = DECL_RTL (exp);
   11615     68331090 :     expand_decl_rtl:
   11616     68331090 :       gcc_assert (decl_rtl);
   11617              : 
   11618              :       /* DECL_MODE might change when TYPE_MODE depends on attribute target
   11619              :          settings for VECTOR_TYPE_P that might switch for the function.  */
   11620     68331090 :       if (currently_expanding_to_rtl
   11621     64670054 :           && code == VAR_DECL && MEM_P (decl_rtl)
   11622     82772703 :           && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
   11623           57 :         decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
   11624              :       else
   11625     68331033 :         decl_rtl = copy_rtx (decl_rtl);
   11626              : 
   11627              :       /* Record writes to register variables.  */
   11628     68331090 :       if (modifier == EXPAND_WRITE
   11629     21473581 :           && REG_P (decl_rtl)
   11630     84031594 :           && HARD_REGISTER_P (decl_rtl))
   11631         2027 :         add_to_hard_reg_set (&crtl->asm_clobbers,
   11632         2027 :                              GET_MODE (decl_rtl), REGNO (decl_rtl));
   11633              : 
   11634              :       /* Ensure variable marked as used even if it doesn't go through
   11635              :          a parser.  If it hasn't be used yet, write out an external
   11636              :          definition.  */
   11637     68331090 :       if (exp)
   11638     39882922 :         TREE_USED (exp) = 1;
   11639              : 
   11640              :       /* Show we haven't gotten RTL for this yet.  */
   11641    108214012 :       temp = 0;
   11642              : 
   11643              :       /* Variables inherited from containing functions should have
   11644              :          been lowered by this point.  */
   11645     39882922 :       if (exp)
   11646              :         {
   11647     39882922 :           tree context = decl_function_context (exp);
   11648     39882922 :           gcc_assert (SCOPE_FILE_SCOPE_P (context)
   11649              :                       || context == current_function_decl
   11650              :                       || TREE_STATIC (exp)
   11651              :                       || DECL_EXTERNAL (exp)
   11652              :                       /* ??? C++ creates functions that are not
   11653              :                          TREE_STATIC.  */
   11654              :                       || TREE_CODE (exp) == FUNCTION_DECL);
   11655              :         }
   11656              : 
   11657              :       /* This is the case of an array whose size is to be determined
   11658              :          from its initializer, while the initializer is still being parsed.
   11659              :          ??? We aren't parsing while expanding anymore.  */
   11660              : 
   11661     68331090 :       if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
   11662       390538 :         temp = validize_mem (decl_rtl);
   11663              : 
   11664              :       /* If DECL_RTL is memory, we are in the normal case and the
   11665              :          address is not valid, get the address into a register.  */
   11666              : 
   11667     67940552 :       else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
   11668              :         {
   11669     18395650 :           if (alt_rtl)
   11670      2005424 :             *alt_rtl = decl_rtl;
   11671     18395650 :           decl_rtl = use_anchored_address (decl_rtl);
   11672     18395650 :           if (modifier != EXPAND_CONST_ADDRESS
   11673     18395650 :               && modifier != EXPAND_SUM
   11674     30525905 :               && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
   11675        17246 :                                                : GET_MODE (decl_rtl),
   11676              :                                                XEXP (decl_rtl, 0),
   11677     12130255 :                                                MEM_ADDR_SPACE (decl_rtl)))
   11678       136829 :             temp = replace_equiv_address (decl_rtl,
   11679              :                                           copy_rtx (XEXP (decl_rtl, 0)));
   11680              :         }
   11681              : 
   11682              :       /* If we got something, return it.  But first, set the alignment
   11683              :          if the address is a register.  */
   11684     18786188 :       if (temp != 0)
   11685              :         {
   11686       527367 :           if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
   11687       495498 :             mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
   11688              :         }
   11689     67803723 :       else if (MEM_P (decl_rtl))
   11690              :         temp = decl_rtl;
   11691              : 
   11692     46542798 :       if (temp != 0)
   11693              :         {
   11694     22283800 :           if (MEM_P (temp)
   11695              :               && modifier != EXPAND_WRITE
   11696     22283800 :               && modifier != EXPAND_MEMORY
   11697              :               && modifier != EXPAND_INITIALIZER
   11698     16430043 :               && modifier != EXPAND_CONST_ADDRESS
   11699      6825628 :               && modifier != EXPAND_SUM
   11700      6825628 :               && !inner_reference_p
   11701      4476799 :               && mode != BLKmode
   11702     26395114 :               && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
   11703        19813 :             temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
   11704        19813 :                                               MEM_ALIGN (temp), NULL_RTX, NULL);
   11705              : 
   11706     22283800 :           return EXTEND_BITINT (temp);
   11707              :         }
   11708              : 
   11709     46047290 :       if (exp)
   11710     17616378 :         dmode = DECL_MODE (exp);
   11711              :       else
   11712     28430912 :         dmode = TYPE_MODE (TREE_TYPE (ssa_name));
   11713              : 
   11714              :       /* If the mode of DECL_RTL does not match that of the decl,
   11715              :          there are two cases: we are dealing with a BLKmode value
   11716              :          that is returned in a register, or we are dealing with
   11717              :          a promoted value.  In the latter case, return a SUBREG
   11718              :          of the wanted mode, but mark it so that we know that it
   11719              :          was already extended.  */
   11720     46047290 :       if (REG_P (decl_rtl)
   11721     45567657 :           && dmode != BLKmode
   11722     45567657 :           && GET_MODE (decl_rtl) != dmode)
   11723              :         {
   11724           82 :           machine_mode pmode;
   11725              : 
   11726              :           /* Get the signedness to be used for this variable.  Ensure we get
   11727              :              the same mode we got when the variable was declared.  */
   11728           82 :           if (code != SSA_NAME)
   11729            0 :             pmode = promote_decl_mode (exp, &unsignedp);
   11730           82 :           else if ((g = SSA_NAME_DEF_STMT (ssa_name))
   11731           82 :                    && gimple_code (g) == GIMPLE_CALL
   11732           84 :                    && !gimple_call_internal_p (g))
   11733            2 :             pmode = promote_function_mode (type, mode, &unsignedp,
   11734            2 :                                            gimple_call_fntype (g),
   11735              :                                            2);
   11736              :           else
   11737           80 :             pmode = promote_ssa_mode (ssa_name, &unsignedp);
   11738           82 :           gcc_assert (GET_MODE (decl_rtl) == pmode);
   11739              : 
   11740              :           /* Some ABIs require scalar floating point modes to be passed
   11741              :              in a wider scalar integer mode.  We need to explicitly
   11742              :              truncate to an integer mode of the correct precision before
   11743              :              using a SUBREG to reinterpret as a floating point value.  */
   11744           82 :           if (SCALAR_FLOAT_MODE_P (mode)
   11745            0 :               && SCALAR_INT_MODE_P (pmode)
   11746           82 :               && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
   11747            0 :             return convert_wider_int_to_float (mode, pmode, decl_rtl);
   11748              : 
   11749           82 :           temp = gen_lowpart_SUBREG (mode, decl_rtl);
   11750           82 :           SUBREG_PROMOTED_VAR_P (temp) = 1;
   11751           82 :           SUBREG_PROMOTED_SET (temp, unsignedp);
   11752           82 :           return EXTEND_BITINT (temp);
   11753              :         }
   11754              : 
   11755     46047208 :       return EXTEND_BITINT (decl_rtl);
   11756              : 
   11757     41510751 :     case INTEGER_CST:
   11758     41510751 :       {
   11759     41510751 :         if (TREE_CODE (type) == BITINT_TYPE)
   11760              :           {
   11761        10635 :             unsigned int prec = TYPE_PRECISION (type);
   11762        10635 :             struct bitint_info info;
   11763        10635 :             bool ok = targetm.c.bitint_type_info (prec, &info);
   11764        10635 :             gcc_assert (ok);
   11765        10635 :             scalar_int_mode limb_mode
   11766        10635 :               = as_a <scalar_int_mode> (info.limb_mode);
   11767        10635 :             unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
   11768        17523 :             if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
   11769              :               {
   11770              :                 /* Emit large/huge _BitInt INTEGER_CSTs into memory.  */
   11771         4435 :                 exp = tree_output_constant_def (exp);
   11772         4435 :                 return expand_expr (exp, target, VOIDmode, modifier);
   11773              :               }
   11774              :           }
   11775              : 
   11776              :         /* Given that TYPE_PRECISION (type) is not always equal to
   11777              :            GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
   11778              :            the former to the latter according to the signedness of the
   11779              :            type.  */
   11780     41506316 :         scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
   11781     41506316 :         temp = immed_wide_int_const
   11782     41506316 :           (wi::to_wide (exp, GET_MODE_PRECISION (int_mode)), int_mode);
   11783     41506316 :         return temp;
   11784              :       }
   11785              : 
   11786       556706 :     case VECTOR_CST:
   11787       556706 :       {
   11788       556706 :         tree tmp = NULL_TREE;
   11789       556706 :         if (VECTOR_MODE_P (mode))
   11790       554091 :           return const_vector_from_tree (exp);
   11791         2615 :         scalar_int_mode int_mode;
   11792         2615 :         if (is_int_mode (mode, &int_mode))
   11793              :           {
   11794          881 :             tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
   11795          881 :             if (type_for_mode)
   11796          881 :               tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
   11797              :                                     type_for_mode, exp);
   11798              :           }
   11799          881 :         if (!tmp)
   11800              :           {
   11801         1734 :             vec<constructor_elt, va_gc> *v;
   11802              :             /* Constructors need to be fixed-length.  FIXME.  */
   11803         1734 :             unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
   11804         1734 :             vec_alloc (v, nunits);
   11805        25569 :             for (unsigned int i = 0; i < nunits; ++i)
   11806        23835 :               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
   11807         1734 :             tmp = build_constructor (type, v);
   11808              :           }
   11809         2615 :         return expand_expr (tmp, ignore ? const0_rtx : target,
   11810         2615 :                             tmode, modifier);
   11811              :       }
   11812              : 
   11813          141 :     case CONST_DECL:
   11814          141 :       if (modifier == EXPAND_WRITE)
   11815              :         {
   11816              :           /* Writing into CONST_DECL is always invalid, but handle it
   11817              :              gracefully.  */
   11818            2 :           addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
   11819            2 :           scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
   11820            2 :           op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
   11821              :                                          EXPAND_NORMAL, as);
   11822            2 :           op0 = memory_address_addr_space (mode, op0, as);
   11823            2 :           temp = gen_rtx_MEM (mode, op0);
   11824            2 :           set_mem_addr_space (temp, as);
   11825            2 :           return temp;
   11826              :         }
   11827          139 :       return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
   11828              : 
   11829       847721 :     case REAL_CST:
   11830              :       /* If optimized, generate immediate CONST_DOUBLE
   11831              :          which will be turned into memory by reload if necessary.
   11832              : 
   11833              :          We used to force a register so that loop.c could see it.  But
   11834              :          this does not allow gen_* patterns to perform optimizations with
   11835              :          the constants.  It also produces two insns in cases like "x = 1.0;".
   11836              :          On most machines, floating-point constants are not permitted in
   11837              :          many insns, so we'd end up copying it to a register in any case.
   11838              : 
   11839              :          Now, we do the copying in expand_binop, if appropriate.  */
   11840       847721 :       return const_double_from_real_value (TREE_REAL_CST (exp),
   11841      1695442 :                                            TYPE_MODE (TREE_TYPE (exp)));
   11842              : 
   11843            0 :     case FIXED_CST:
   11844            0 :       return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
   11845              :                                            TYPE_MODE (TREE_TYPE (exp)));
   11846              : 
   11847        18393 :     case COMPLEX_CST:
   11848              :       /* Handle evaluating a complex constant in a CONCAT target.  */
   11849        18393 :       if (original_target && GET_CODE (original_target) == CONCAT)
   11850              :         {
   11851          217 :           rtx rtarg, itarg;
   11852              : 
   11853          217 :           mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
   11854          217 :           rtarg = XEXP (original_target, 0);
   11855          217 :           itarg = XEXP (original_target, 1);
   11856              : 
   11857              :           /* Move the real and imaginary parts separately.  */
   11858          217 :           op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, EXPAND_NORMAL);
   11859          217 :           op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, EXPAND_NORMAL);
   11860              : 
   11861          217 :           if (op0 != rtarg)
   11862          217 :             emit_move_insn (rtarg, op0);
   11863          217 :           if (op1 != itarg)
   11864          217 :             emit_move_insn (itarg, op1);
   11865              : 
   11866          217 :           return original_target;
   11867              :         }
   11868              : 
   11869              :       /* fall through */
   11870              : 
   11871       189547 :     case STRING_CST:
   11872       189547 :       temp = expand_expr_constant (exp, 1, modifier);
   11873              : 
   11874              :       /* temp contains a constant address.
   11875              :          On RISC machines where a constant address isn't valid,
   11876              :          make some insns to get that address into a register.  */
   11877       189547 :       if (modifier != EXPAND_CONST_ADDRESS
   11878              :           && modifier != EXPAND_INITIALIZER
   11879       189547 :           && modifier != EXPAND_SUM
   11880       208119 :           && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
   11881        18572 :                                             MEM_ADDR_SPACE (temp)))
   11882           12 :         return replace_equiv_address (temp,
   11883           12 :                                       copy_rtx (XEXP (temp, 0)));
   11884              :       return temp;
   11885              : 
   11886            0 :     case POLY_INT_CST:
   11887            0 :       return immed_wide_int_const (poly_int_cst_value (exp), mode);
   11888              : 
   11889         1466 :     case SAVE_EXPR:
   11890         1466 :       {
   11891         1466 :         tree val = treeop0;
   11892         1466 :         rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
   11893              :                                       inner_reference_p);
   11894              : 
   11895         1466 :         if (!SAVE_EXPR_RESOLVED_P (exp))
   11896              :           {
   11897              :             /* We can indeed still hit this case, typically via builtin
   11898              :                expanders calling save_expr immediately before expanding
   11899              :                something.  Assume this means that we only have to deal
   11900              :                with non-BLKmode values.  */
   11901         1419 :             gcc_assert (GET_MODE (ret) != BLKmode);
   11902              : 
   11903         1419 :             val = build_decl (curr_insn_location (),
   11904         1419 :                               VAR_DECL, NULL, TREE_TYPE (exp));
   11905         1419 :             DECL_ARTIFICIAL (val) = 1;
   11906         1419 :             DECL_IGNORED_P (val) = 1;
   11907         1419 :             treeop0 = val;
   11908         1419 :             TREE_OPERAND (exp, 0) = treeop0;
   11909         1419 :             SAVE_EXPR_RESOLVED_P (exp) = 1;
   11910              : 
   11911         1419 :             if (!CONSTANT_P (ret))
   11912         1419 :               ret = copy_to_reg (ret);
   11913         1419 :             SET_DECL_RTL (val, ret);
   11914              :           }
   11915              : 
   11916              :         return ret;
   11917              :       }
   11918              : 
   11919              : 
   11920       172776 :     case CONSTRUCTOR:
   11921              :       /* If we don't need the result, just ensure we evaluate any
   11922              :          subexpressions.  */
   11923       172776 :       if (ignore)
   11924              :         {
   11925              :           unsigned HOST_WIDE_INT idx;
   11926              :           tree value;
   11927              : 
   11928            0 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
   11929            0 :             expand_expr (value, const0_rtx, VOIDmode, EXPAND_NORMAL);
   11930              : 
   11931            0 :           return const0_rtx;
   11932              :         }
   11933              : 
   11934       172776 :       return expand_constructor (exp, target, modifier, false);
   11935              : 
   11936       853068 :     case TARGET_MEM_REF:
   11937       853068 :       {
   11938       853068 :         addr_space_t as
   11939       853068 :           = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
   11940       853068 :         unsigned int align;
   11941              : 
   11942       853068 :         op0 = addr_for_mem_ref (exp, as, true);
   11943       853068 :         op0 = memory_address_addr_space (mode, op0, as);
   11944       853068 :         temp = gen_rtx_MEM (mode, op0);
   11945       853068 :         set_mem_attributes (temp, exp, 0);
   11946       853068 :         set_mem_addr_space (temp, as);
   11947       853068 :         align = get_object_alignment (exp);
   11948       853068 :         if (modifier != EXPAND_WRITE
   11949       853068 :             && modifier != EXPAND_MEMORY
   11950       587637 :             && mode != BLKmode
   11951      1434298 :             && align < GET_MODE_ALIGNMENT (mode))
   11952        53681 :           temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
   11953              :                                             align, NULL_RTX, NULL);
   11954       853068 :         return EXTEND_BITINT (temp);
   11955              :       }
   11956              : 
   11957      6547969 :     case MEM_REF:
   11958      6547969 :       {
   11959      6547969 :         const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
   11960      6547969 :         addr_space_t as
   11961      6547969 :           = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
   11962      6547969 :         machine_mode address_mode;
   11963      6547969 :         tree base = TREE_OPERAND (exp, 0);
   11964      6547969 :         gimple *def_stmt;
   11965      6547969 :         unsigned align;
   11966              :         /* Handle expansion of non-aliased memory with non-BLKmode.  That
   11967              :            might end up in a register.  */
   11968      6547969 :         if (mem_ref_refers_to_non_mem_p (exp))
   11969              :           {
   11970        76284 :             poly_int64 offset = mem_ref_offset (exp).force_shwi ();
   11971        76284 :             base = TREE_OPERAND (base, 0);
   11972        76284 :             poly_uint64 type_size;
   11973        76284 :             if (known_eq (offset, 0)
   11974        42252 :                 && !reverse
   11975        42252 :                 && poly_int_tree_p (TYPE_SIZE (type), &type_size)
   11976       160788 :                 && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
   11977        16672 :               return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
   11978        16672 :                                   target, tmode, modifier);
   11979        59612 :             unsigned align;
   11980        59612 :             if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
   11981              :               {
   11982          214 :                 temp = assign_stack_temp (DECL_MODE (base),
   11983          428 :                                           GET_MODE_SIZE (DECL_MODE (base)));
   11984          214 :                 store_expr (base, temp, 0, false, false);
   11985          214 :                 temp = adjust_address (temp, TYPE_MODE (type), offset);
   11986          214 :                 if (TYPE_MODE (type) == BLKmode)
   11987          193 :                   set_mem_size (temp, int_size_in_bytes (type));
   11988              :                 /* When the original ref was misaligned so will be the
   11989              :                    access to the stack temporary.  Not all targets handle
   11990              :                    this correctly, some will ICE in sanity checking.
   11991              :                    Handle this by doing bitfield extraction when necessary.  */
   11992           42 :                 else if ((align = get_object_alignment (exp))
   11993           21 :                          < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
   11994            3 :                   temp
   11995            3 :                     = expand_misaligned_mem_ref (temp, TYPE_MODE (type),
   11996              :                                                  unsignedp, align,
   11997              :                                                  modifier == EXPAND_STACK_PARM
   11998              :                                                  ? NULL_RTX : target, NULL);
   11999          214 :                 return temp;
   12000              :               }
   12001              :             /* When the access is fully outside of the underlying object
   12002              :                expand the offset as zero.  This avoids out-of-bound
   12003              :                BIT_FIELD_REFs and generates smaller code for these cases
   12004              :                with UB.  */
   12005        59398 :             type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
   12006       118796 :             if (!ranges_maybe_overlap_p (offset, type_size, 0,
   12007       118796 :                                          GET_MODE_SIZE (DECL_MODE (base))))
   12008           37 :               offset = 0;
   12009        59398 :             exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
   12010        59398 :                           bitsize_int (offset * BITS_PER_UNIT));
   12011        59398 :             REF_REVERSE_STORAGE_ORDER (exp) = reverse;
   12012        59398 :             return expand_expr (exp, target, tmode, modifier);
   12013              :           }
   12014      6471685 :         address_mode = targetm.addr_space.address_mode (as);
   12015      6471685 :         if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
   12016              :           {
   12017           38 :             tree mask = gimple_assign_rhs2 (def_stmt);
   12018           38 :             base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
   12019              :                            gimple_assign_rhs1 (def_stmt), mask);
   12020           38 :             TREE_OPERAND (exp, 0) = base;
   12021              :           }
   12022      6471685 :         align = get_object_alignment (exp);
   12023      6471685 :         op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
   12024      6471685 :         op0 = memory_address_addr_space (mode, op0, as);
   12025      6471685 :         if (!integer_zerop (TREE_OPERAND (exp, 1)))
   12026              :           {
   12027      1966290 :             rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
   12028      1966290 :             op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
   12029      1966290 :             op0 = memory_address_addr_space (mode, op0, as);
   12030              :           }
   12031      6471685 :         temp = gen_rtx_MEM (mode, op0);
   12032      6471685 :         set_mem_attributes (temp, exp, 0);
   12033      6471685 :         set_mem_addr_space (temp, as);
   12034      6471685 :         if (TREE_THIS_VOLATILE (exp))
   12035        12299 :           MEM_VOLATILE_P (temp) = 1;
   12036      6471685 :         if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
   12037              :           return temp;
   12038      3850782 :         if (!inner_reference_p
   12039      2006365 :             && mode != BLKmode
   12040      5796869 :             && align < GET_MODE_ALIGNMENT (mode))
   12041       138134 :           temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
   12042              :                                             modifier == EXPAND_STACK_PARM
   12043              :                                             ? NULL_RTX : target, alt_rtl);
   12044      3850782 :         if (reverse)
   12045            7 :           temp = flip_storage_order (mode, temp);
   12046      3850782 :         return EXTEND_BITINT (temp);
   12047              :       }
   12048              : 
   12049       607643 :     case ARRAY_REF:
   12050              : 
   12051       607643 :       {
   12052       607643 :         tree array = treeop0;
   12053       607643 :         tree index = treeop1;
   12054       607643 :         tree init;
   12055              : 
   12056              :         /* Fold an expression like: "foo"[2].
   12057              :            This is not done in fold so it won't happen inside &.
   12058              :            Don't fold if this is for wide characters since it's too
   12059              :            difficult to do correctly and this is a very rare case.  */
   12060              : 
   12061       607643 :         if (modifier != EXPAND_CONST_ADDRESS
   12062       607643 :             && modifier != EXPAND_INITIALIZER
   12063       607643 :             && modifier != EXPAND_MEMORY)
   12064              :           {
   12065       607534 :             tree t = fold_read_from_constant_string (exp);
   12066              : 
   12067       607534 :             if (t)
   12068            0 :               return expand_expr (t, target, tmode, modifier);
   12069              :           }
   12070              : 
   12071              :         /* If this is a constant index into a constant array,
   12072              :            just get the value from the array.  Handle both the cases when
   12073              :            we have an explicit constructor and when our operand is a variable
   12074              :            that was declared const.  */
   12075              : 
   12076       607643 :         if (modifier != EXPAND_CONST_ADDRESS
   12077              :             && modifier != EXPAND_INITIALIZER
   12078              :             && modifier != EXPAND_MEMORY
   12079       607534 :             && TREE_CODE (array) == CONSTRUCTOR
   12080            0 :             && ! TREE_SIDE_EFFECTS (array)
   12081       607643 :             && TREE_CODE (index) == INTEGER_CST)
   12082              :           {
   12083              :             unsigned HOST_WIDE_INT ix;
   12084              :             tree field, value;
   12085              : 
   12086            0 :             FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
   12087              :                                       field, value)
   12088            0 :               if (tree_int_cst_equal (field, index))
   12089              :                 {
   12090            0 :                   if (!TREE_SIDE_EFFECTS (value)
   12091            0 :                       && TREE_CODE (value) != RAW_DATA_CST)
   12092            0 :                     return expand_expr (fold (value), target, tmode, modifier);
   12093              :                   break;
   12094              :                 }
   12095              :           }
   12096              : 
   12097       607643 :         else if (optimize >= 1
   12098              :                  && modifier != EXPAND_CONST_ADDRESS
   12099       341668 :                  && modifier != EXPAND_INITIALIZER
   12100       341668 :                  && modifier != EXPAND_MEMORY
   12101       341563 :                  && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
   12102        10228 :                  && TREE_CODE (index) == INTEGER_CST
   12103         2014 :                  && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
   12104       607784 :                  && (init = ctor_for_folding (array)) != error_mark_node)
   12105              :           {
   12106          100 :             if (init == NULL_TREE)
   12107              :               {
   12108            5 :                 tree value = build_zero_cst (type);
   12109            5 :                 if (TREE_CODE (value) == CONSTRUCTOR)
   12110              :                   {
   12111              :                     /* If VALUE is a CONSTRUCTOR, this optimization is only
   12112              :                        useful if this doesn't store the CONSTRUCTOR into
   12113              :                        memory.  If it does, it is more efficient to just
   12114              :                        load the data from the array directly.  */
   12115            5 :                     rtx ret = expand_constructor (value, target,
   12116              :                                                   modifier, true);
   12117            5 :                     if (ret == NULL_RTX)
   12118              :                       value = NULL_TREE;
   12119              :                   }
   12120              : 
   12121              :                 if (value)
   12122            0 :                   return expand_expr (value, target, tmode, modifier);
   12123              :               }
   12124           95 :             else if (TREE_CODE (init) == CONSTRUCTOR)
   12125              :               {
   12126              :                 unsigned HOST_WIDE_INT ix;
   12127              :                 tree field, value;
   12128              : 
   12129          190 :                 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
   12130              :                                           field, value)
   12131          173 :                   if (tree_int_cst_equal (field, index))
   12132              :                     {
   12133           77 :                       if (TREE_SIDE_EFFECTS (value)
   12134           77 :                           || TREE_CODE (value) == RAW_DATA_CST)
   12135              :                         break;
   12136              : 
   12137           77 :                       if (TREE_CODE (value) == CONSTRUCTOR)
   12138              :                         {
   12139              :                           /* If VALUE is a CONSTRUCTOR, this
   12140              :                              optimization is only useful if
   12141              :                              this doesn't store the CONSTRUCTOR
   12142              :                              into memory.  If it does, it is more
   12143              :                              efficient to just load the data from
   12144              :                              the array directly.  */
   12145           72 :                           rtx ret = expand_constructor (value, target,
   12146              :                                                         modifier, true);
   12147           72 :                           if (ret == NULL_RTX)
   12148              :                             break;
   12149              :                         }
   12150              : 
   12151           39 :                       return expand_expr (fold (value), target, tmode,
   12152           39 :                                           modifier);
   12153              :                     }
   12154              :               }
   12155            1 :             else if (TREE_CODE (init) == STRING_CST)
   12156              :               {
   12157            1 :                 tree low_bound = array_ref_low_bound (exp);
   12158            1 :                 tree index1 = fold_convert_loc (loc, sizetype, treeop1);
   12159              : 
   12160              :                 /* Optimize the special case of a zero lower bound.
   12161              : 
   12162              :                    We convert the lower bound to sizetype to avoid problems
   12163              :                    with constant folding.  E.g. suppose the lower bound is
   12164              :                    1 and its mode is QI.  Without the conversion
   12165              :                       (ARRAY + (INDEX - (unsigned char)1))
   12166              :                    becomes
   12167              :                       (ARRAY + (-(unsigned char)1) + INDEX)
   12168              :                    which becomes
   12169              :                       (ARRAY + 255 + INDEX).  Oops!  */
   12170            1 :                 if (!integer_zerop (low_bound))
   12171            0 :                   index1 = size_diffop_loc (loc, index1,
   12172              :                                             fold_convert_loc (loc, sizetype,
   12173              :                                                               low_bound));
   12174              : 
   12175            1 :                 if (tree_fits_uhwi_p (index1)
   12176            2 :                     && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
   12177              :                   {
   12178            0 :                     tree char_type = TREE_TYPE (TREE_TYPE (init));
   12179            0 :                     scalar_int_mode char_mode;
   12180              : 
   12181       607604 :                     if (is_int_mode (TYPE_MODE (char_type), &char_mode)
   12182            0 :                         && GET_MODE_SIZE (char_mode) == 1)
   12183            0 :                       return gen_int_mode (TREE_STRING_POINTER (init)
   12184            0 :                                            [TREE_INT_CST_LOW (index1)],
   12185              :                                            char_mode);
   12186              :                   }
   12187              :               }
   12188              :           }
   12189              :       }
   12190       607604 :       goto normal_inner_ref;
   12191              : 
   12192      3650549 :     case COMPONENT_REF:
   12193      3650549 :       gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
   12194              :       /* Fall through.  */
   12195      4510805 :     case BIT_FIELD_REF:
   12196      4510805 :     case ARRAY_RANGE_REF:
   12197      3650549 :     normal_inner_ref:
   12198      4510805 :       {
   12199      4510805 :         machine_mode mode1, mode2;
   12200      4510805 :         poly_int64 bitsize, bitpos, bytepos;
   12201      4510805 :         tree offset;
   12202      4510805 :         int reversep, volatilep = 0;
   12203      4510805 :         tree tem
   12204      4510805 :           = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
   12205              :                                  &unsignedp, &reversep, &volatilep);
   12206      4510805 :         rtx orig_op0, memloc;
   12207      4510805 :         bool clear_mem_expr = false;
   12208      4510805 :         bool must_force_mem;
   12209              : 
   12210              :         /* If we got back the original object, something is wrong.  Perhaps
   12211              :            we are evaluating an expression too early.  In any event, don't
   12212              :            infinitely recurse.  */
   12213      4510805 :         gcc_assert (tem != exp);
   12214              : 
   12215              :         /* Make sure bitpos is not negative, this can wreak havoc later.  */
   12216      4510805 :         if (maybe_lt (bitpos, 0))
   12217              :           {
   12218          249 :             gcc_checking_assert (offset == NULL_TREE);
   12219          249 :             offset = size_int (bits_to_bytes_round_down (bitpos));
   12220          249 :             bitpos = num_trailing_bits (bitpos);
   12221              :           }
   12222              : 
   12223              :         /* If we have either an offset, a BLKmode result, or a reference
   12224              :            outside the underlying object, we must force it to memory.
   12225              :            Such a case can occur in Ada if we have unchecked conversion
   12226              :            of an expression from a scalar type to an aggregate type or
   12227              :            for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
   12228              :            passed a partially uninitialized object or a view-conversion
   12229              :            to a larger size.  */
   12230      9021610 :         must_force_mem = offset != NULL_TREE
   12231      4230031 :                          || mode1 == BLKmode
   12232      8669969 :                          || (mode == BLKmode
   12233            0 :                              && !int_mode_for_size (bitsize, 1).exists ());
   12234              : 
   12235       526655 :         const enum expand_modifier tem_modifier
   12236              :           = must_force_mem
   12237              :             ? EXPAND_MEMORY
   12238      4159164 :             : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
   12239              : 
   12240              :         /* If TEM's type is a union of variable size, pass TARGET to the inner
   12241              :            computation, since it will need a temporary and TARGET is known
   12242              :            to have to do.  This occurs in unchecked conversion in Ada.  */
   12243      4510805 :         const rtx tem_target
   12244      4510805 :           = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
   12245        36641 :             && COMPLETE_TYPE_P (TREE_TYPE (tem))
   12246        36636 :             && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
   12247            0 :             && modifier != EXPAND_STACK_PARM
   12248      4510805 :             ? target
   12249              :             : NULL_RTX;
   12250              : 
   12251      9021610 :         orig_op0 = op0
   12252      4510805 :           = expand_expr_real (tem, tem_target, VOIDmode, tem_modifier, NULL,
   12253              :                               true);
   12254              : 
   12255              :         /* If the field has a mode, we want to access it in the
   12256              :            field's mode, not the computed mode.
   12257              :            If a MEM has VOIDmode (external with incomplete type),
   12258              :            use BLKmode for it instead.  */
   12259      4510805 :         if (MEM_P (op0))
   12260              :           {
   12261      4178935 :             if (mode1 != VOIDmode)
   12262      4017043 :               op0 = adjust_address (op0, mode1, 0);
   12263       161892 :             else if (GET_MODE (op0) == VOIDmode)
   12264            0 :               op0 = adjust_address (op0, BLKmode, 0);
   12265              :           }
   12266              : 
   12267      4510805 :         mode2
   12268      4510805 :           = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
   12269              : 
   12270              :         /* See above for the rationale.  */
   12271      9021610 :         if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
   12272      2832482 :           must_force_mem = true;
   12273              : 
   12274              :         /* Handle CONCAT first.  */
   12275      4510805 :         if (GET_CODE (op0) == CONCAT && !must_force_mem)
   12276              :           {
   12277          134 :             if (known_eq (bitpos, 0)
   12278          246 :                 && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
   12279          118 :                 && COMPLEX_MODE_P (mode1)
   12280          113 :                 && COMPLEX_MODE_P (GET_MODE (op0))
   12281          473 :                 && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
   12282          226 :                     == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
   12283              :               {
   12284          113 :                 if (reversep)
   12285            0 :                   op0 = flip_storage_order (GET_MODE (op0), op0);
   12286          113 :                 if (mode1 != GET_MODE (op0))
   12287              :                   {
   12288              :                     rtx parts[2];
   12289            0 :                     for (int i = 0; i < 2; i++)
   12290              :                       {
   12291            0 :                         rtx op = read_complex_part (op0, i != 0);
   12292            0 :                         if (GET_CODE (op) == SUBREG)
   12293            0 :                           op = force_reg (GET_MODE (op), op);
   12294            0 :                         temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
   12295            0 :                         if (temp)
   12296              :                           op = temp;
   12297              :                         else
   12298              :                           {
   12299            0 :                             if (!REG_P (op) && !MEM_P (op))
   12300            0 :                               op = force_reg (GET_MODE (op), op);
   12301            0 :                             op = gen_lowpart (GET_MODE_INNER (mode1), op);
   12302              :                           }
   12303            0 :                         parts[i] = op;
   12304              :                       }
   12305            0 :                     op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
   12306              :                   }
   12307          113 :                 return op0;
   12308              :               }
   12309           21 :             if (known_eq (bitpos, 0)
   12310           20 :                 && known_eq (bitsize,
   12311              :                              GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
   12312           23 :                 && maybe_ne (bitsize, 0))
   12313              :               {
   12314              :                 op0 = XEXP (op0, 0);
   12315              :                 mode2 = GET_MODE (op0);
   12316              :               }
   12317           19 :             else if (known_eq (bitpos,
   12318              :                                GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
   12319            4 :                      && known_eq (bitsize,
   12320              :                                   GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
   12321            0 :                      && maybe_ne (bitpos, 0)
   12322           19 :                      && maybe_ne (bitsize, 0))
   12323              :               {
   12324            0 :                 op0 = XEXP (op0, 1);
   12325            0 :                 bitpos = 0;
   12326            0 :                 mode2 = GET_MODE (op0);
   12327              :               }
   12328              :             else
   12329              :               /* Otherwise force into memory.  */
   12330              :               must_force_mem = true;
   12331              :           }
   12332              : 
   12333              :         /* If this is a constant, put it in a register if it is a legitimate
   12334              :            constant and we don't need a memory reference.  */
   12335      4510692 :         if (CONSTANT_P (op0)
   12336           25 :             && mode2 != BLKmode
   12337           25 :             && targetm.legitimate_constant_p (mode2, op0)
   12338      4510705 :             && !must_force_mem)
   12339           13 :           op0 = force_reg (mode2, op0);
   12340              : 
   12341              :         /* Otherwise, if this is a constant, try to force it to the constant
   12342              :            pool.  Note that back-ends, e.g. MIPS, may refuse to do so if it
   12343              :            is a legitimate constant.  */
   12344      4510679 :         else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
   12345           12 :           op0 = validize_mem (memloc);
   12346              : 
   12347              :         /* Otherwise, if this is a constant or the object is not in memory
   12348              :            and need be, put it there.  */
   12349      4510667 :         else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
   12350              :           {
   12351         1094 :             machine_mode tem_mode = TYPE_MODE (TREE_TYPE (tem));
   12352         1094 :             poly_int64 size;
   12353         1094 :             if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
   12354            0 :               size = max_int_size_in_bytes (TREE_TYPE (tem));
   12355         1094 :             unsigned int align = TREE_CODE (tem) == SSA_NAME
   12356         1094 :                                  ? TYPE_ALIGN (TREE_TYPE (tem))
   12357         1094 :                                  : get_object_alignment (tem);
   12358         1094 :             if (STRICT_ALIGNMENT)
   12359              :               {
   12360              :                 /* For STRICT_ALIGNMENT targets, when we force the operand to
   12361              :                    memory, we may need to increase the alignment to meet the
   12362              :                    expectation in later RTL lowering passes.  The increased
   12363              :                    alignment is capped by MAX_SUPPORTED_STACK_ALIGNMENT.  */
   12364              :                 if (tem_mode != BLKmode)
   12365              :                   align = MAX (align, GET_MODE_ALIGNMENT (tem_mode));
   12366              :                 else
   12367              :                   align = MAX (align, TYPE_ALIGN (TREE_TYPE (tem)));
   12368              :                 align = MIN (align, (unsigned) MAX_SUPPORTED_STACK_ALIGNMENT);
   12369              :               }
   12370         1094 :             memloc = assign_stack_local (tem_mode, size, align);
   12371         1094 :             emit_move_insn (memloc, op0);
   12372         1094 :             op0 = memloc;
   12373         1094 :             clear_mem_expr = true;
   12374              :           }
   12375              : 
   12376      4510692 :         if (offset)
   12377              :           {
   12378       280774 :             machine_mode address_mode;
   12379       280774 :             rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
   12380              :                                           EXPAND_SUM);
   12381              : 
   12382       280774 :             gcc_assert (MEM_P (op0));
   12383              : 
   12384       280774 :             address_mode = get_address_mode (op0);
   12385       280774 :             if (GET_MODE (offset_rtx) != address_mode)
   12386              :               {
   12387              :                 /* We cannot be sure that the RTL in offset_rtx is valid outside
   12388              :                    of a memory address context, so force it into a register
   12389              :                    before attempting to convert it to the desired mode.  */
   12390          422 :                 offset_rtx = force_operand (offset_rtx, NULL_RTX);
   12391          422 :                 offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
   12392              :               }
   12393              : 
   12394              :             /* See the comment in expand_assignment for the rationale.  */
   12395       280774 :             if (mode1 != VOIDmode
   12396       280540 :                 && maybe_ne (bitpos, 0)
   12397        75050 :                 && maybe_gt (bitsize, 0)
   12398       355824 :                 && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
   12399       355285 :                 && multiple_p (bitpos, bitsize)
   12400       149022 :                 && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
   12401       355285 :                 && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
   12402              :               {
   12403        74158 :                 op0 = adjust_address (op0, mode1, bytepos);
   12404        74158 :                 bitpos = 0;
   12405              :               }
   12406              : 
   12407       280774 :             op0 = offset_address (op0, offset_rtx,
   12408              :                                   highest_pow2_factor (offset));
   12409              :           }
   12410              : 
   12411              :         /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
   12412              :            record its alignment as BIGGEST_ALIGNMENT.  */
   12413      4510692 :         if (MEM_P (op0)
   12414      4180041 :             && known_eq (bitpos, 0)
   12415      1431953 :             && offset != 0
   12416      4790408 :             && is_aligning_offset (offset, tem))
   12417            0 :           set_mem_align (op0, BIGGEST_ALIGNMENT);
   12418              : 
   12419              :         /* Don't forget about volatility even if this is a bitfield.  */
   12420      4510692 :         if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
   12421              :           {
   12422          528 :             if (op0 == orig_op0)
   12423          158 :               op0 = copy_rtx (op0);
   12424              : 
   12425          528 :             MEM_VOLATILE_P (op0) = 1;
   12426              :           }
   12427              : 
   12428      4510692 :         if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
   12429              :           {
   12430            6 :             if (op0 == orig_op0)
   12431            0 :               op0 = copy_rtx (op0);
   12432              : 
   12433            6 :             set_mem_align (op0, BITS_PER_UNIT);
   12434              :           }
   12435              : 
   12436              :         /* In cases where an aligned union has an unaligned object
   12437              :            as a field, we might be extracting a BLKmode value from
   12438              :            an integer-mode (e.g., SImode) object.  Handle this case
   12439              :            by doing the extract into an object as wide as the field
   12440              :            (which we know to be the width of a basic mode), then
   12441              :            storing into memory, and changing the mode to BLKmode.  */
   12442      4510692 :         if (mode1 == VOIDmode
   12443      4277358 :             || REG_P (op0) || GET_CODE (op0) == SUBREG
   12444      4018115 :             || (mode1 != BLKmode && ! direct_load[(int) mode1]
   12445        26573 :                 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
   12446        22414 :                 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
   12447              :                 && modifier != EXPAND_CONST_ADDRESS
   12448        15371 :                 && modifier != EXPAND_INITIALIZER
   12449        15371 :                 && modifier != EXPAND_MEMORY)
   12450              :             /* If the bitfield is volatile and the bitsize
   12451              :                is narrower than the access size of the bitfield,
   12452              :                we need to extract bitfields from the access.  */
   12453      4002744 :             || (volatilep && TREE_CODE (exp) == COMPONENT_REF
   12454         1395 :                 && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
   12455           10 :                 && mode1 != BLKmode
   12456           20 :                 && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
   12457              :             /* If the field isn't aligned enough to fetch as a memref,
   12458              :                fetch it as a bit field.  */
   12459      4002735 :             || (mode1 != BLKmode
   12460      3931019 :                 && (((MEM_P (op0)
   12461      3931019 :                       ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
   12462      7718615 :                         || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
   12463            0 :                       : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
   12464            0 :                         || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
   12465        75032 :                      && modifier != EXPAND_MEMORY
   12466        75032 :                      && ((modifier == EXPAND_CONST_ADDRESS
   12467        75032 :                           || modifier == EXPAND_INITIALIZER)
   12468        75032 :                          ? STRICT_ALIGNMENT
   12469        75032 :                          : targetm.slow_unaligned_access (mode1,
   12470        75032 :                                                           MEM_ALIGN (op0))))
   12471      3931019 :                     || !multiple_p (bitpos, BITS_PER_UNIT)))
   12472              :             /* If the type and the field are a constant size and the
   12473              :                size of the type isn't the same size as the bitfield,
   12474              :                we must use bitfield operations.  */
   12475     12444446 :             || (known_size_p (bitsize)
   12476      4002735 :                 && TYPE_SIZE (TREE_TYPE (exp))
   12477      4002735 :                 && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
   12478      4002735 :                 && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
   12479              :                              bitsize)))
   12480              :           {
   12481       507986 :             machine_mode ext_mode = mode;
   12482              : 
   12483       507986 :             if (ext_mode == BLKmode
   12484       507986 :                 && ! (target != 0 && MEM_P (op0)
   12485           22 :                       && MEM_P (target)
   12486           22 :                       && multiple_p (bitpos, BITS_PER_UNIT)))
   12487            3 :               ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
   12488              : 
   12489       507986 :             if (ext_mode == BLKmode)
   12490              :               {
   12491           25 :                 if (target == 0)
   12492            3 :                   target = assign_temp (type, 1, 1);
   12493              : 
   12494              :                 /* ??? Unlike the similar test a few lines below, this one is
   12495              :                    very likely obsolete.  */
   12496           25 :                 if (known_eq (bitsize, 0))
   12497              :                   return target;
   12498              : 
   12499              :                 /* In this case, BITPOS must start at a byte boundary and
   12500              :                    TARGET, if specified, must be a MEM.  */
   12501           25 :                 gcc_assert (MEM_P (op0)
   12502              :                             && (!target || MEM_P (target)));
   12503              : 
   12504           25 :                 bytepos = exact_div (bitpos, BITS_PER_UNIT);
   12505           25 :                 poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
   12506           50 :                 emit_block_move (target,
   12507              :                                  adjust_address (op0, VOIDmode, bytepos),
   12508           25 :                                  gen_int_mode (bytesize, Pmode),
   12509              :                                  (modifier == EXPAND_STACK_PARM
   12510              :                                   ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
   12511              : 
   12512           25 :                 return target;
   12513              :               }
   12514              : 
   12515              :             /* If we have nothing to extract, the result will be 0 for targets
   12516              :                with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise.  Always
   12517              :                return 0 for the sake of consistency, as reading a zero-sized
   12518              :                bitfield is valid in Ada and the value is fully specified.  */
   12519       507961 :             if (known_eq (bitsize, 0))
   12520            0 :               return const0_rtx;
   12521              : 
   12522       507961 :             op0 = validize_mem (op0);
   12523              : 
   12524       507961 :             if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
   12525        54652 :               mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12526              : 
   12527              :             /* If the result has aggregate type and the extraction is done in
   12528              :                an integral mode, then the field may be not aligned on a byte
   12529              :                boundary; in this case, if it has reverse storage order, it
   12530              :                needs to be extracted as a scalar field with reverse storage
   12531              :                order and put back into memory order afterwards.  */
   12532       507961 :             if (AGGREGATE_TYPE_P (type)
   12533         4755 :                 && GET_MODE_CLASS (ext_mode) == MODE_INT)
   12534         4673 :               reversep = TYPE_REVERSE_STORAGE_ORDER (type);
   12535              : 
   12536       507961 :             gcc_checking_assert (known_ge (bitpos, 0));
   12537       520623 :             op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
   12538              :                                      (modifier == EXPAND_STACK_PARM
   12539              :                                       ? NULL_RTX : target),
   12540              :                                      ext_mode, ext_mode, reversep, alt_rtl);
   12541              : 
   12542              :             /* If the result has aggregate type and the mode of OP0 is an
   12543              :                integral mode then, if BITSIZE is narrower than this mode
   12544              :                and this is for big-endian data, we must put the field
   12545              :                into the high-order bits.  And we must also put it back
   12546              :                into memory order if it has been previously reversed.  */
   12547       507961 :             scalar_int_mode op0_mode;
   12548       507961 :             if (AGGREGATE_TYPE_P (type)
   12549       507961 :                 && is_int_mode (GET_MODE (op0), &op0_mode))
   12550              :               {
   12551         4673 :                 HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
   12552              : 
   12553         4673 :                 gcc_checking_assert (known_le (bitsize, size));
   12554         4673 :                 if (maybe_lt (bitsize, size)
   12555         4673 :                     && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
   12556            0 :                   op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
   12557              :                                       size - bitsize, op0, 1);
   12558              : 
   12559         4673 :                 if (reversep)
   12560            0 :                   op0 = flip_storage_order (op0_mode, op0);
   12561              :               }
   12562              : 
   12563              :             /* If the result type is BLKmode, store the data into a temporary
   12564              :                of the appropriate type, but with the mode corresponding to the
   12565              :                mode for the data we have (op0's mode).  */
   12566       507961 :             if (mode == BLKmode)
   12567              :               {
   12568            0 :                 rtx new_rtx
   12569            0 :                   = assign_stack_temp_for_type (ext_mode,
   12570            0 :                                                 GET_MODE_BITSIZE (ext_mode),
   12571              :                                                 type);
   12572            0 :                 emit_move_insn (new_rtx, op0);
   12573            0 :                 op0 = copy_rtx (new_rtx);
   12574            0 :                 PUT_MODE (op0, BLKmode);
   12575              :               }
   12576              : 
   12577       507961 :             return op0;
   12578              :           }
   12579              : 
   12580              :         /* If the result is BLKmode, use that to access the object
   12581              :            now as well.  */
   12582      4002706 :         if (mode == BLKmode)
   12583        71691 :           mode1 = BLKmode;
   12584              : 
   12585              :         /* Get a reference to just this component.  */
   12586      4002706 :         bytepos = bits_to_bytes_round_down (bitpos);
   12587      4002706 :         if (modifier == EXPAND_CONST_ADDRESS
   12588      4002706 :             || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
   12589       165590 :           op0 = adjust_address_nv (op0, mode1, bytepos);
   12590              :         else
   12591      3837116 :           op0 = adjust_address (op0, mode1, bytepos);
   12592              : 
   12593      4002706 :         if (op0 == orig_op0)
   12594       127693 :           op0 = copy_rtx (op0);
   12595              : 
   12596              :         /* Don't set memory attributes if the base expression is
   12597              :            SSA_NAME that got expanded as a MEM or a CONSTANT.  In that case,
   12598              :            we should just honor its original memory attributes.  */
   12599      4002706 :         if (!(TREE_CODE (tem) == SSA_NAME
   12600         8755 :               && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
   12601      3993951 :           set_mem_attributes (op0, exp, 0);
   12602              : 
   12603      4002706 :         if (REG_P (XEXP (op0, 0)))
   12604       655136 :           mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12605              : 
   12606              :         /* If op0 is a temporary because the original expressions was forced
   12607              :            to memory, clear MEM_EXPR so that the original expression cannot
   12608              :            be marked as addressable through MEM_EXPR of the temporary.  */
   12609      4002706 :         if (clear_mem_expr)
   12610         1060 :           set_mem_expr (op0, NULL_TREE);
   12611              : 
   12612      4002706 :         MEM_VOLATILE_P (op0) |= volatilep;
   12613              : 
   12614      4002706 :         if (reversep
   12615              :             && modifier != EXPAND_MEMORY
   12616          491 :             && modifier != EXPAND_WRITE)
   12617          491 :           op0 = flip_storage_order (mode1, op0);
   12618              : 
   12619      4002706 :         op0 = EXTEND_BITINT (op0);
   12620              : 
   12621      4002706 :         if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
   12622              :             || modifier == EXPAND_CONST_ADDRESS
   12623            0 :             || modifier == EXPAND_INITIALIZER)
   12624              :           return op0;
   12625              : 
   12626            0 :         if (target == 0)
   12627            0 :           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
   12628              : 
   12629            0 :         convert_move (target, op0, unsignedp);
   12630            0 :         return target;
   12631              :       }
   12632              : 
   12633        83545 :     case OBJ_TYPE_REF:
   12634        83545 :       return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
   12635              : 
   12636      6596671 :     case CALL_EXPR:
   12637              :       /* All valid uses of __builtin_va_arg_pack () are removed during
   12638              :          inlining.  */
   12639      6596671 :       if (CALL_EXPR_VA_ARG_PACK (exp))
   12640            6 :         error ("invalid use of %<__builtin_va_arg_pack ()%>");
   12641      6596671 :       {
   12642      6596671 :         tree fndecl = get_callee_fndecl (exp), attr;
   12643              : 
   12644      6596671 :         if (fndecl
   12645              :             /* Don't diagnose the error attribute in thunks, those are
   12646              :                artificially created.  */
   12647      6408484 :             && !CALL_FROM_THUNK_P (exp)
   12648     13001585 :             && (attr = lookup_attribute ("error",
   12649      6404914 :                                          DECL_ATTRIBUTES (fndecl))) != NULL)
   12650              :           {
   12651            5 :             const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
   12652           10 :             error ("call to %qs declared with attribute error: %s",
   12653              :                    identifier_to_locale (ident),
   12654            5 :                    TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
   12655              :           }
   12656      6596671 :         if (fndecl
   12657              :             /* Don't diagnose the warning attribute in thunks, those are
   12658              :                artificially created.  */
   12659      6408484 :             && !CALL_FROM_THUNK_P (exp)
   12660     13001585 :             && (attr = lookup_attribute ("warning",
   12661      6404914 :                                          DECL_ATTRIBUTES (fndecl))) != NULL)
   12662              :           {
   12663           17 :             const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
   12664           34 :             warning_at (EXPR_LOCATION (exp),
   12665           17 :                         OPT_Wattribute_warning,
   12666              :                         "call to %qs declared with attribute warning: %s",
   12667              :                         identifier_to_locale (ident),
   12668           17 :                         TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
   12669              :           }
   12670              : 
   12671              :         /* Check for a built-in function.  */
   12672      6596671 :         if (fndecl && fndecl_built_in_p (fndecl))
   12673              :           {
   12674      1966895 :             gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
   12675      1966895 :             return expand_builtin (exp, target, subtarget, tmode, ignore);
   12676              :           }
   12677              :       }
   12678      4629776 :       temp = expand_call (exp, target, ignore);
   12679      4629775 :       return EXTEND_BITINT (temp);
   12680              : 
   12681       334614 :     case VIEW_CONVERT_EXPR:
   12682       334614 :       op0 = NULL_RTX;
   12683              : 
   12684              :       /* If we are converting to BLKmode, try to avoid an intermediate
   12685              :          temporary by fetching an inner memory reference.  */
   12686       334614 :       if (mode == BLKmode
   12687        74214 :           && poly_int_tree_p (TYPE_SIZE (type))
   12688        74214 :           && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
   12689       334614 :           && handled_component_p (treeop0))
   12690              :       {
   12691            0 :         machine_mode mode1;
   12692            0 :         poly_int64 bitsize, bitpos, bytepos;
   12693            0 :         tree offset;
   12694            0 :         int reversep, volatilep = 0;
   12695            0 :         tree tem
   12696            0 :           = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
   12697              :                                  &unsignedp, &reversep, &volatilep);
   12698              : 
   12699              :         /* ??? We should work harder and deal with non-zero offsets.  */
   12700            0 :         if (!offset
   12701            0 :             && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
   12702            0 :             && !reversep
   12703            0 :             && known_size_p (bitsize)
   12704            0 :             && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
   12705              :           {
   12706              :             /* See the normal_inner_ref case for the rationale.  */
   12707            0 :             rtx orig_op0
   12708            0 :               = expand_expr_real (tem,
   12709            0 :                                   (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
   12710            0 :                                    && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
   12711              :                                        != INTEGER_CST)
   12712            0 :                                    && modifier != EXPAND_STACK_PARM
   12713              :                                    ? target : NULL_RTX),
   12714              :                                   VOIDmode,
   12715              :                                   modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
   12716              :                                   NULL, true);
   12717              : 
   12718            0 :             if (MEM_P (orig_op0))
   12719              :               {
   12720            0 :                 op0 = orig_op0;
   12721              : 
   12722              :                 /* Get a reference to just this component.  */
   12723            0 :                 if (modifier == EXPAND_CONST_ADDRESS
   12724              :                     || modifier == EXPAND_SUM
   12725            0 :                     || modifier == EXPAND_INITIALIZER)
   12726            0 :                   op0 = adjust_address_nv (op0, mode, bytepos);
   12727              :                 else
   12728            0 :                   op0 = adjust_address (op0, mode, bytepos);
   12729              : 
   12730            0 :                 if (op0 == orig_op0)
   12731            0 :                   op0 = copy_rtx (op0);
   12732              : 
   12733            0 :                 set_mem_attributes (op0, treeop0, 0);
   12734            0 :                 if (REG_P (XEXP (op0, 0)))
   12735            0 :                   mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12736              : 
   12737            0 :                 MEM_VOLATILE_P (op0) |= volatilep;
   12738              :               }
   12739              :           }
   12740              :       }
   12741              : 
   12742            0 :       if (!op0)
   12743       334614 :         op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
   12744       334614 :                                 NULL, inner_reference_p || mode == BLKmode);
   12745              : 
   12746              :       /* If the input and output modes are both the same, we are done.  */
   12747       334614 :       if (mode == GET_MODE (op0))
   12748              :         ;
   12749              :       /* Similarly if the output mode is BLKmode and input is a MEM,
   12750              :          adjust_address done below is all we need.  */
   12751       144553 :       else if (mode == BLKmode && MEM_P (op0))
   12752              :         ;
   12753              :       /* If neither mode is BLKmode, and both modes are the same size
   12754              :          then we can use gen_lowpart.  */
   12755              :       else if (mode != BLKmode
   12756       144520 :                && GET_MODE (op0) != BLKmode
   12757       143183 :                && known_eq (GET_MODE_PRECISION (mode),
   12758              :                             GET_MODE_PRECISION (GET_MODE (op0)))
   12759       139286 :                && !COMPLEX_MODE_P (GET_MODE (op0)))
   12760              :         {
   12761       137884 :           if (GET_CODE (op0) == SUBREG)
   12762           99 :             op0 = force_reg (GET_MODE (op0), op0);
   12763       137884 :           temp = gen_lowpart_common (mode, op0);
   12764       137884 :           if (temp)
   12765              :             op0 = temp;
   12766              :           else
   12767              :             {
   12768        27299 :               if (!REG_P (op0) && !MEM_P (op0))
   12769           18 :                 op0 = force_reg (GET_MODE (op0), op0);
   12770        27299 :               op0 = gen_lowpart (mode, op0);
   12771              :             }
   12772              :         }
   12773              :       /* If both types are integral, convert from one mode to the other.  */
   12774         6667 :       else if (INTEGRAL_TYPE_P (type)
   12775         3140 :                && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
   12776            0 :                && mode != BLKmode
   12777         6667 :                && GET_MODE (op0) != BLKmode)
   12778            0 :         op0 = convert_modes (mode, GET_MODE (op0), op0,
   12779            0 :                              TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   12780              :       /* If the output type is a bit-field type, do an extraction.  */
   12781         6667 :       else if (reduce_bit_field
   12782            1 :                && mode != BLKmode
   12783            1 :                && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
   12784            0 :         return extract_bit_field (op0, TYPE_PRECISION (type), 0,
   12785            0 :                                   TYPE_UNSIGNED (type), NULL_RTX,
   12786              :                                   mode, mode, false, NULL);
   12787              :       /* As a last resort, spill op0 to memory, and reload it in a
   12788              :          different mode.  */
   12789         6667 :       else if (!MEM_P (op0))
   12790              :         {
   12791              :           /* If the operand is not a MEM, force it into memory.  Since we
   12792              :              are going to be changing the mode of the MEM, don't call
   12793              :              force_const_mem for constants because we don't allow pool
   12794              :              constants to change mode.  */
   12795         5320 :           tree inner_type = TREE_TYPE (treeop0);
   12796              : 
   12797         5320 :           gcc_assert (!TREE_ADDRESSABLE (exp));
   12798              : 
   12799         5320 :           if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
   12800         5316 :             target
   12801              :               = assign_stack_temp_for_type
   12802         5316 :                 (TYPE_MODE (inner_type),
   12803        10632 :                  GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
   12804              : 
   12805         5320 :           emit_move_insn (target, op0);
   12806         5320 :           op0 = target;
   12807              : 
   12808         5320 :           if (reduce_bit_field && mode != BLKmode)
   12809            1 :             return extract_bit_field (op0, TYPE_PRECISION (type), 0,
   12810            1 :                                       TYPE_UNSIGNED (type), NULL_RTX,
   12811              :                                       mode, mode, false, NULL);
   12812              :         }
   12813              : 
   12814              :       /* If OP0 is (now) a MEM, we need to deal with alignment issues.  If the
   12815              :          output type is such that the operand is known to be aligned, indicate
   12816              :          that it is.  Otherwise, we need only be concerned about alignment for
   12817              :          non-BLKmode results.  */
   12818       334613 :       if (MEM_P (op0))
   12819              :         {
   12820       127428 :           enum insn_code icode;
   12821              : 
   12822       127428 :           if (modifier != EXPAND_WRITE
   12823       127428 :               && modifier != EXPAND_MEMORY
   12824       127428 :               && !inner_reference_p
   12825       127427 :               && mode != BLKmode
   12826       180641 :               && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
   12827              :             {
   12828              :               /* If the target does have special handling for unaligned
   12829              :                  loads of mode then use them.  */
   12830        15682 :               if ((icode = optab_handler (movmisalign_optab, mode))
   12831              :                   != CODE_FOR_nothing)
   12832              :                 {
   12833         1791 :                   rtx reg;
   12834              : 
   12835         1791 :                   op0 = adjust_address (op0, mode, 0);
   12836              :                   /* We've already validated the memory, and we're creating a
   12837              :                      new pseudo destination.  The predicates really can't
   12838              :                      fail.  */
   12839         1791 :                   reg = gen_reg_rtx (mode);
   12840              : 
   12841              :                   /* Nor can the insn generator.  */
   12842         1791 :                   rtx_insn *insn = GEN_FCN (icode) (reg, op0);
   12843         1791 :                   emit_insn (insn);
   12844         1791 :                   return reg;
   12845              :                 }
   12846              :               else if (STRICT_ALIGNMENT)
   12847              :                 {
   12848              :                   poly_uint64 mode_size = GET_MODE_SIZE (mode);
   12849              :                   poly_uint64 temp_size = mode_size;
   12850              :                   if (GET_MODE (op0) != BLKmode)
   12851              :                     temp_size = upper_bound (temp_size,
   12852              :                                              GET_MODE_SIZE (GET_MODE (op0)));
   12853              :                   rtx new_rtx
   12854              :                     = assign_stack_temp_for_type (mode, temp_size, type);
   12855              :                   rtx new_with_op0_mode
   12856              :                     = adjust_address (new_rtx, GET_MODE (op0), 0);
   12857              : 
   12858              :                   gcc_assert (!TREE_ADDRESSABLE (exp));
   12859              : 
   12860              :                   if (GET_MODE (op0) == BLKmode)
   12861              :                     {
   12862              :                       rtx size_rtx = gen_int_mode (mode_size, Pmode);
   12863              :                       emit_block_move (new_with_op0_mode, op0, size_rtx,
   12864              :                                        (modifier == EXPAND_STACK_PARM
   12865              :                                         ? BLOCK_OP_CALL_PARM
   12866              :                                         : BLOCK_OP_NORMAL));
   12867              :                     }
   12868              :                   else
   12869              :                     emit_move_insn (new_with_op0_mode, op0);
   12870              : 
   12871              :                   op0 = new_rtx;
   12872              :                 }
   12873              :             }
   12874              : 
   12875       125637 :           op0 = adjust_address (op0, mode, 0);
   12876              :         }
   12877              : 
   12878              :       return op0;
   12879              : 
   12880        63220 :     case MODIFY_EXPR:
   12881        63220 :       {
   12882        63220 :         tree lhs = treeop0;
   12883        63220 :         tree rhs = treeop1;
   12884        63220 :         gcc_assert (ignore);
   12885              : 
   12886              :         /* Check for |= or &= of a bitfield of size one into another bitfield
   12887              :            of size 1.  In this case, (unless we need the result of the
   12888              :            assignment) we can do this more efficiently with a
   12889              :            test followed by an assignment, if necessary.
   12890              : 
   12891              :            ??? At this point, we can't get a BIT_FIELD_REF here.  But if
   12892              :            things change so we do, this code should be enhanced to
   12893              :            support it.  */
   12894        63220 :         if (TREE_CODE (lhs) == COMPONENT_REF
   12895        60236 :             && (TREE_CODE (rhs) == BIT_IOR_EXPR
   12896        60236 :                 || TREE_CODE (rhs) == BIT_AND_EXPR)
   12897            0 :             && TREE_OPERAND (rhs, 0) == lhs
   12898            0 :             && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
   12899            0 :             && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
   12900        63220 :             && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
   12901              :           {
   12902            0 :             rtx_code_label *label = gen_label_rtx ();
   12903            0 :             int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
   12904            0 :             profile_probability prob = profile_probability::uninitialized ();
   12905            0 :             if (value)
   12906            0 :               jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
   12907              :             else
   12908            0 :               jumpif (TREE_OPERAND (rhs, 1), label, prob);
   12909            0 :             expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value),
   12910              :                                false);
   12911            0 :             do_pending_stack_adjust ();
   12912            0 :             emit_label (label);
   12913            0 :             return const0_rtx;
   12914              :           }
   12915              : 
   12916        63220 :         expand_assignment (lhs, rhs, false);
   12917        63220 :         return const0_rtx;
   12918              :       }
   12919              : 
   12920     12856295 :     case ADDR_EXPR:
   12921     12856295 :       return expand_expr_addr_expr (exp, target, tmode, modifier);
   12922              : 
   12923       153607 :     case REALPART_EXPR:
   12924       153607 :       op0 = expand_normal (treeop0);
   12925       153607 :       return read_complex_part (op0, false);
   12926              : 
   12927       177377 :     case IMAGPART_EXPR:
   12928       177377 :       op0 = expand_normal (treeop0);
   12929       177377 :       return read_complex_part (op0, true);
   12930              : 
   12931            0 :     case RETURN_EXPR:
   12932            0 :     case LABEL_EXPR:
   12933            0 :     case GOTO_EXPR:
   12934            0 :     case SWITCH_EXPR:
   12935            0 :     case ASM_EXPR:
   12936              :       /* Expanded in cfgexpand.cc.  */
   12937            0 :       gcc_unreachable ();
   12938              : 
   12939            0 :     case TRY_CATCH_EXPR:
   12940            0 :     case CATCH_EXPR:
   12941            0 :     case EH_FILTER_EXPR:
   12942            0 :     case TRY_FINALLY_EXPR:
   12943            0 :     case EH_ELSE_EXPR:
   12944              :       /* Lowered by tree-eh.cc.  */
   12945            0 :       gcc_unreachable ();
   12946              : 
   12947            0 :     case WITH_CLEANUP_EXPR:
   12948            0 :     case CLEANUP_POINT_EXPR:
   12949            0 :     case TARGET_EXPR:
   12950            0 :     case CASE_LABEL_EXPR:
   12951            0 :     case VA_ARG_EXPR:
   12952            0 :     case BIND_EXPR:
   12953            0 :     case INIT_EXPR:
   12954            0 :     case CONJ_EXPR:
   12955            0 :     case COMPOUND_EXPR:
   12956            0 :     case PREINCREMENT_EXPR:
   12957            0 :     case PREDECREMENT_EXPR:
   12958            0 :     case POSTINCREMENT_EXPR:
   12959            0 :     case POSTDECREMENT_EXPR:
   12960            0 :     case LOOP_EXPR:
   12961            0 :     case EXIT_EXPR:
   12962            0 :     case COMPOUND_LITERAL_EXPR:
   12963              :       /* Lowered by gimplify.cc.  */
   12964            0 :       gcc_unreachable ();
   12965              : 
   12966            0 :     case FDESC_EXPR:
   12967              :       /* Function descriptors are not valid except for as
   12968              :          initialization constants, and should not be expanded.  */
   12969            0 :       gcc_unreachable ();
   12970              : 
   12971          258 :     case WITH_SIZE_EXPR:
   12972              :       /* WITH_SIZE_EXPR expands to its first argument.  The caller should
   12973              :          have pulled out the size to use in whatever context it needed.  */
   12974          258 :       return expand_expr_real (treeop0, original_target, tmode,
   12975          258 :                                modifier, alt_rtl, inner_reference_p);
   12976              : 
   12977      1823366 :     default:
   12978      1823366 :       return expand_expr_real_2 (&ops, target, tmode, modifier);
   12979              :     }
   12980              : }
   12981              : #undef EXTEND_BITINT
   12982              : 
   12983              : /* Subroutine of above: reduce EXP to the precision of TYPE (in the
   12984              :    signedness of TYPE), possibly returning the result in TARGET.
   12985              :    TYPE is known to be a partial integer type.  */
   12986              : static rtx
   12987        85347 : reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
   12988              : {
   12989        85347 :   scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
   12990        85347 :   HOST_WIDE_INT prec = TYPE_PRECISION (type);
   12991        85347 :   gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
   12992              :               && (!target || GET_MODE (target) == mode));
   12993              : 
   12994              :   /* For constant values, reduce using wide_int_to_tree. */
   12995        85347 :   if (poly_int_rtx_p (exp))
   12996              :     {
   12997            0 :       auto value = wi::to_poly_wide (exp, mode);
   12998            0 :       tree t = wide_int_to_tree (type, value);
   12999            0 :       return expand_expr (t, target, VOIDmode, EXPAND_NORMAL);
   13000              :     }
   13001        85347 :   else if (TYPE_UNSIGNED (type))
   13002              :     {
   13003        67216 :       rtx mask = immed_wide_int_const
   13004        67216 :         (wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
   13005        67216 :       return expand_and (mode, exp, mask, target);
   13006              :     }
   13007              :   else
   13008              :     {
   13009        18131 :       int count = GET_MODE_PRECISION (mode) - prec;
   13010        18131 :       exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
   13011        18131 :       return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
   13012              :     }
   13013              : }
   13014              : 
   13015              : /* Subroutine of above: returns true if OFFSET corresponds to an offset that
   13016              :    when applied to the address of EXP produces an address known to be
   13017              :    aligned more than BIGGEST_ALIGNMENT.  */
   13018              : 
   13019              : static bool
   13020       279716 : is_aligning_offset (const_tree offset, const_tree exp)
   13021              : {
   13022              :   /* Strip off any conversions.  */
   13023       299581 :   while (CONVERT_EXPR_P (offset))
   13024        19865 :     offset = TREE_OPERAND (offset, 0);
   13025              : 
   13026              :   /* We must now have a BIT_AND_EXPR with a constant that is one less than
   13027              :      power of 2 and which is larger than BIGGEST_ALIGNMENT.  */
   13028       279716 :   if (TREE_CODE (offset) != BIT_AND_EXPR
   13029            0 :       || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
   13030            0 :       || compare_tree_int (TREE_OPERAND (offset, 1),
   13031            0 :                            BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
   13032       279716 :       || !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
   13033       279716 :     return false;
   13034              : 
   13035              :   /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
   13036              :      It must be NEGATE_EXPR.  Then strip any more conversions.  */
   13037            0 :   offset = TREE_OPERAND (offset, 0);
   13038            0 :   while (CONVERT_EXPR_P (offset))
   13039            0 :     offset = TREE_OPERAND (offset, 0);
   13040              : 
   13041            0 :   if (TREE_CODE (offset) != NEGATE_EXPR)
   13042              :     return false;
   13043              : 
   13044            0 :   offset = TREE_OPERAND (offset, 0);
   13045            0 :   while (CONVERT_EXPR_P (offset))
   13046            0 :     offset = TREE_OPERAND (offset, 0);
   13047              : 
   13048              :   /* This must now be the address of EXP.  */
   13049            0 :   return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
   13050              : }
   13051              : 
   13052              : /* Return a STRING_CST corresponding to ARG's constant initializer either
   13053              :    if it's a string constant, or, when VALREP is set, any other constant,
   13054              :    or null otherwise.
   13055              :    On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
   13056              :    within the byte string that ARG is references.  If nonnull set *MEM_SIZE
   13057              :    to the size of the byte string.  If nonnull, set *DECL to the constant
   13058              :    declaration ARG refers to.  */
   13059              : 
   13060              : static tree
   13061     15272717 : constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
   13062              :                       bool valrep = false)
   13063              : {
   13064     15272717 :   tree dummy = NULL_TREE;
   13065     15272717 :   if (!mem_size)
   13066        10895 :     mem_size = &dummy;
   13067              : 
   13068              :   /* Store the type of the original expression before conversions
   13069              :      via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
   13070              :      removed.  */
   13071     15272717 :   tree argtype = TREE_TYPE (arg);
   13072              : 
   13073     15272717 :   tree array;
   13074     15272717 :   STRIP_NOPS (arg);
   13075              : 
   13076              :   /* Non-constant index into the character array in an ARRAY_REF
   13077              :      expression or null.  */
   13078     15272717 :   tree varidx = NULL_TREE;
   13079              : 
   13080     15272717 :   poly_int64 base_off = 0;
   13081              : 
   13082     15272717 :   if (TREE_CODE (arg) == ADDR_EXPR)
   13083              :     {
   13084      6257957 :       arg = TREE_OPERAND (arg, 0);
   13085      6257957 :       tree ref = arg;
   13086      6257957 :       if (TREE_CODE (arg) == ARRAY_REF)
   13087              :         {
   13088       559702 :           tree idx = TREE_OPERAND (arg, 1);
   13089       559702 :           if (TREE_CODE (idx) != INTEGER_CST)
   13090              :             {
   13091              :               /* From a pointer (but not array) argument extract the variable
   13092              :                  index to prevent get_addr_base_and_unit_offset() from failing
   13093              :                  due to it.  Use it later to compute the non-constant offset
   13094              :                  into the string and return it to the caller.  */
   13095       167022 :               varidx = idx;
   13096       167022 :               ref = TREE_OPERAND (arg, 0);
   13097              : 
   13098       167022 :               if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
   13099              :                 return NULL_TREE;
   13100              : 
   13101        28216 :               if (!integer_zerop (array_ref_low_bound (arg)))
   13102              :                 return NULL_TREE;
   13103              : 
   13104        27450 :               if (!integer_onep (array_ref_element_size (arg)))
   13105              :                 return NULL_TREE;
   13106              :             }
   13107              :         }
   13108      6117167 :       array = get_addr_base_and_unit_offset (ref, &base_off);
   13109      6117167 :       if (!array
   13110      6069726 :           || (TREE_CODE (array) != VAR_DECL
   13111      6069726 :               && TREE_CODE (array) != CONST_DECL
   13112      3821776 :               && TREE_CODE (array) != STRING_CST))
   13113              :         return NULL_TREE;
   13114              :     }
   13115      9014760 :   else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
   13116              :     {
   13117        26448 :       tree arg0 = TREE_OPERAND (arg, 0);
   13118        26448 :       tree arg1 = TREE_OPERAND (arg, 1);
   13119              : 
   13120        26448 :       tree offset;
   13121        26448 :       tree str = string_constant (arg0, &offset, mem_size, decl);
   13122        26448 :       if (!str)
   13123              :         {
   13124        17144 :            str = string_constant (arg1, &offset, mem_size, decl);
   13125        17144 :            arg1 = arg0;
   13126              :         }
   13127              : 
   13128        17144 :       if (str)
   13129              :         {
   13130              :           /* Avoid pointers to arrays (see bug 86622).  */
   13131         9304 :           if (POINTER_TYPE_P (TREE_TYPE (arg))
   13132         9304 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
   13133         2100 :               && !(decl && !*decl)
   13134        12104 :               && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
   13135         1400 :                    && tree_fits_uhwi_p (*mem_size)
   13136         1400 :                    && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
   13137         2100 :             return NULL_TREE;
   13138              : 
   13139         7204 :           tree type = TREE_TYPE (offset);
   13140         7204 :           arg1 = fold_convert (type, arg1);
   13141         7204 :           *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
   13142         7204 :           return str;
   13143              :         }
   13144              :       return NULL_TREE;
   13145              :     }
   13146      8988312 :   else if (TREE_CODE (arg) == SSA_NAME)
   13147              :     {
   13148      3851654 :       gimple *stmt = SSA_NAME_DEF_STMT (arg);
   13149      3851654 :       if (!is_gimple_assign (stmt))
   13150              :         return NULL_TREE;
   13151              : 
   13152      1014043 :       tree rhs1 = gimple_assign_rhs1 (stmt);
   13153      1014043 :       tree_code code = gimple_assign_rhs_code (stmt);
   13154      1014043 :       if (code == ADDR_EXPR)
   13155       230441 :         return string_constant (rhs1, ptr_offset, mem_size, decl);
   13156       783602 :       else if (code != POINTER_PLUS_EXPR)
   13157              :         return NULL_TREE;
   13158              : 
   13159       188627 :       tree offset;
   13160       188627 :       if (tree str = string_constant (rhs1, &offset, mem_size, decl))
   13161              :         {
   13162              :           /* Avoid pointers to arrays (see bug 86622).  */
   13163        20871 :           if (POINTER_TYPE_P (TREE_TYPE (rhs1))
   13164        20871 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
   13165        18174 :               && !(decl && !*decl)
   13166        37167 :               && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
   13167         8148 :                    && tree_fits_uhwi_p (*mem_size)
   13168         8148 :                    && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
   13169        15634 :             return NULL_TREE;
   13170              : 
   13171         5237 :           tree rhs2 = gimple_assign_rhs2 (stmt);
   13172         5237 :           tree type = TREE_TYPE (offset);
   13173         5237 :           rhs2 = fold_convert (type, rhs2);
   13174         5237 :           *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
   13175         5237 :           return str;
   13176              :         }
   13177              :       return NULL_TREE;
   13178              :     }
   13179      5136658 :   else if (DECL_P (arg))
   13180              :     array = arg;
   13181              :   else
   13182              :     return NULL_TREE;
   13183              : 
   13184      8424365 :   tree offset = wide_int_to_tree (sizetype, base_off);
   13185      8424365 :   if (varidx)
   13186              :     {
   13187         2238 :       if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
   13188              :         return NULL_TREE;
   13189              : 
   13190         1727 :       gcc_assert (TREE_CODE (arg) == ARRAY_REF);
   13191         1727 :       tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
   13192         1727 :       if (TREE_CODE (chartype) != INTEGER_TYPE)
   13193              :         return NULL;
   13194              : 
   13195         1571 :       offset = fold_convert (sizetype, varidx);
   13196              :     }
   13197              : 
   13198      8423698 :   if (TREE_CODE (array) == STRING_CST)
   13199              :     {
   13200      3443064 :       *ptr_offset = fold_convert (sizetype, offset);
   13201      3443064 :       *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
   13202      3443064 :       if (decl)
   13203       760720 :         *decl = NULL_TREE;
   13204      3443064 :       gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
   13205              :                            >= TREE_STRING_LENGTH (array));
   13206              :       return array;
   13207              :     }
   13208              : 
   13209      4980634 :   tree init = ctor_for_folding (array);
   13210      4980634 :   if (!init || init == error_mark_node)
   13211              :     return NULL_TREE;
   13212              : 
   13213       157775 :   if (valrep)
   13214              :     {
   13215        57784 :       HOST_WIDE_INT cstoff;
   13216        57784 :       if (!base_off.is_constant (&cstoff))
   13217              :         return NULL_TREE;
   13218              : 
   13219              :       /* Check that the host and target are sane.  */
   13220        57784 :       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
   13221              :         return NULL_TREE;
   13222              : 
   13223        57784 :       HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
   13224        57784 :       if (typesz <= 0 || (int) typesz != typesz)
   13225              :         return NULL_TREE;
   13226              : 
   13227        57631 :       HOST_WIDE_INT size = typesz;
   13228        57631 :       if (VAR_P (array)
   13229        57619 :           && DECL_SIZE_UNIT (array)
   13230       115250 :           && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
   13231              :         {
   13232        57619 :           size = tree_to_shwi (DECL_SIZE_UNIT (array));
   13233        57619 :           gcc_checking_assert (size >= typesz);
   13234              :         }
   13235              : 
   13236              :       /* If value representation was requested convert the initializer
   13237              :          for the whole array or object into a string of bytes forming
   13238              :          its value representation and return it.  */
   13239        57631 :       unsigned char *bytes = XNEWVEC (unsigned char, size);
   13240        57631 :       int r = native_encode_initializer (init, bytes, size);
   13241        57631 :       if (r < typesz)
   13242              :         {
   13243           58 :           XDELETEVEC (bytes);
   13244           58 :           return NULL_TREE;
   13245              :         }
   13246              : 
   13247        57573 :       if (r < size)
   13248            0 :         memset (bytes + r, '\0', size - r);
   13249              : 
   13250        57573 :       const char *p = reinterpret_cast<const char *>(bytes);
   13251        57573 :       init = build_string_literal (size, p, char_type_node);
   13252        57573 :       init = TREE_OPERAND (init, 0);
   13253        57573 :       init = TREE_OPERAND (init, 0);
   13254        57573 :       XDELETE (bytes);
   13255              : 
   13256        57573 :       *mem_size = size_int (TREE_STRING_LENGTH (init));
   13257        57573 :       *ptr_offset = wide_int_to_tree (ssizetype, base_off);
   13258              : 
   13259        57573 :       if (decl)
   13260            0 :         *decl = array;
   13261              : 
   13262        57573 :       return init;
   13263              :     }
   13264              : 
   13265        99991 :   if (TREE_CODE (init) == CONSTRUCTOR)
   13266              :     {
   13267              :       /* Convert the 64-bit constant offset to a wider type to avoid
   13268              :          overflow and use it to obtain the initializer for the subobject
   13269              :          it points into.  */
   13270        80437 :       offset_int wioff;
   13271        80437 :       if (!base_off.is_constant (&wioff))
   13272          155 :         return NULL_TREE;
   13273              : 
   13274        80437 :       wioff *= BITS_PER_UNIT;
   13275        80437 :       if (!wi::fits_uhwi_p (wioff))
   13276              :         return NULL_TREE;
   13277              : 
   13278        80329 :       base_off = wioff.to_uhwi ();
   13279        80329 :       unsigned HOST_WIDE_INT fieldoff = 0;
   13280        80329 :       init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
   13281              :                                   &fieldoff);
   13282        80329 :       if (!init || init == error_mark_node)
   13283              :         return NULL_TREE;
   13284              : 
   13285        80282 :       HOST_WIDE_INT cstoff;
   13286        80282 :       if (!base_off.is_constant (&cstoff))
   13287              :         return NULL_TREE;
   13288              : 
   13289        80282 :       cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
   13290        80282 :       tree off = build_int_cst (sizetype, cstoff);
   13291        80282 :       if (varidx)
   13292          944 :         offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
   13293              :       else
   13294              :         offset = off;
   13295              :     }
   13296              : 
   13297        99836 :   *ptr_offset = offset;
   13298              : 
   13299        99836 :   tree inittype = TREE_TYPE (init);
   13300              : 
   13301        99836 :   if (TREE_CODE (init) == INTEGER_CST
   13302        99836 :       && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
   13303         1093 :           || TYPE_MAIN_VARIANT (inittype) == char_type_node))
   13304              :     {
   13305              :       /* Check that the host and target are sane.  */
   13306          905 :       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
   13307              :         return NULL_TREE;
   13308              : 
   13309              :       /* For a reference to (address of) a single constant character,
   13310              :          store the native representation of the character in CHARBUF.
   13311              :          If the reference is to an element of an array or a member
   13312              :          of a struct, only consider narrow characters until ctors
   13313              :          for wide character arrays are transformed to STRING_CSTs
   13314              :          like those for narrow arrays.  */
   13315          905 :       unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
   13316          905 :       int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
   13317          905 :       if (len > 0)
   13318              :         {
   13319              :           /* Construct a string literal with elements of INITTYPE and
   13320              :              the representation above.  Then strip
   13321              :              the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST.  */
   13322          905 :           init = build_string_literal (len, (char *)charbuf, inittype);
   13323          905 :           init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
   13324              :         }
   13325              :     }
   13326              : 
   13327        99836 :   tree initsize = TYPE_SIZE_UNIT (inittype);
   13328              : 
   13329        99836 :   if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
   13330              :     {
   13331              :       /* Fold an empty/zero constructor for an implicitly initialized
   13332              :          object or subobject into the empty string.  */
   13333              : 
   13334              :       /* Determine the character type from that of the original
   13335              :          expression.  */
   13336         9342 :       tree chartype = argtype;
   13337         9342 :       if (POINTER_TYPE_P (chartype))
   13338         9335 :         chartype = TREE_TYPE (chartype);
   13339        14968 :       while (TREE_CODE (chartype) == ARRAY_TYPE)
   13340         5626 :         chartype = TREE_TYPE (chartype);
   13341              : 
   13342         9342 :       if (INTEGRAL_TYPE_P (chartype)
   13343         9342 :           && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
   13344              :         {
   13345              :           /* Convert a char array to an empty STRING_CST having an array
   13346              :              of the expected type and size.  */
   13347         9133 :           if (!initsize)
   13348         3090 :             initsize = integer_zero_node;
   13349         6043 :           else if (!tree_fits_uhwi_p (initsize))
   13350              :             return NULL_TREE;
   13351              : 
   13352         9127 :           unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
   13353         9127 :           if (size > (unsigned HOST_WIDE_INT) INT_MAX)
   13354              :             return NULL_TREE;
   13355              : 
   13356         9127 :           init = build_string_literal (size, NULL, chartype, size);
   13357         9127 :           init = TREE_OPERAND (init, 0);
   13358         9127 :           init = TREE_OPERAND (init, 0);
   13359              : 
   13360         9127 :           *ptr_offset = integer_zero_node;
   13361              :         }
   13362              :     }
   13363              : 
   13364        99830 :   if (decl)
   13365        54160 :     *decl = array;
   13366              : 
   13367        99830 :   if (TREE_CODE (init) != STRING_CST)
   13368              :     return NULL_TREE;
   13369              : 
   13370        68350 :   *mem_size = initsize;
   13371              : 
   13372        68350 :   gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
   13373              : 
   13374              :   return init;
   13375              : }
   13376              : 
   13377              : /* Return STRING_CST if an ARG corresponds to a string constant or zero
   13378              :    if it doesn't.  If we return nonzero, set *PTR_OFFSET to the (possibly
   13379              :    non-constant) offset in bytes within the string that ARG is accessing.
   13380              :    If MEM_SIZE is non-zero the storage size of the memory is returned.
   13381              :    If DECL is non-zero the constant declaration is returned if available.  */
   13382              : 
   13383              : tree
   13384     10641742 : string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
   13385              : {
   13386     10641742 :   return constant_byte_string (arg, ptr_offset, mem_size, decl, false);
   13387              : }
   13388              : 
   13389              : /* Similar to string_constant, return a STRING_CST corresponding
   13390              :    to the value representation of the first argument if it's
   13391              :    a constant.  */
   13392              : 
   13393              : tree
   13394      4630975 : byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
   13395              : {
   13396      4630975 :   return constant_byte_string (arg, ptr_offset, mem_size, decl, true);
   13397              : }
   13398              : 
   13399              : /* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
   13400              :    is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
   13401              :    for C2 > 0 to x & C3 == C2
   13402              :    for C2 < 0 to x & C3 == (C2 & C3).  */
   13403              : enum tree_code
   13404           35 : maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
   13405              : {
   13406           35 :   gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
   13407           35 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13408           35 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13409           35 :   tree type = TREE_TYPE (*arg0);
   13410           35 :   scalar_int_mode mode;
   13411           35 :   if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
   13412              :     return code;
   13413           70 :   if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
   13414           35 :       || TYPE_PRECISION (type) <= 1
   13415           35 :       || TYPE_UNSIGNED (type)
   13416              :       /* Signed x % c == 0 should have been optimized into unsigned modulo
   13417              :          earlier.  */
   13418           35 :       || integer_zerop (*arg1)
   13419              :       /* If c is known to be non-negative, modulo will be expanded as unsigned
   13420              :          modulo.  */
   13421           70 :       || get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1)
   13422            0 :     return code;
   13423              : 
   13424              :   /* x % c == d where d < 0 && d <= -c should be always false.  */
   13425           35 :   if (tree_int_cst_sgn (*arg1) == -1
   13426           51 :       && -wi::to_widest (treeop1) >= wi::to_widest (*arg1))
   13427              :     return code;
   13428              : 
   13429           35 :   int prec = TYPE_PRECISION (type);
   13430           35 :   wide_int w = wi::to_wide (treeop1) - 1;
   13431           35 :   w |= wi::shifted_mask (0, prec - 1, true, prec);
   13432           35 :   tree c3 = wide_int_to_tree (type, w);
   13433           35 :   tree c4 = *arg1;
   13434           35 :   if (tree_int_cst_sgn (*arg1) == -1)
   13435           16 :     c4 = wide_int_to_tree (type, w & wi::to_wide (*arg1));
   13436              : 
   13437           35 :   rtx op0 = expand_normal (treeop0);
   13438           35 :   treeop0 = make_tree (TREE_TYPE (treeop0), op0);
   13439              : 
   13440           35 :   bool speed_p = optimize_insn_for_speed_p ();
   13441              : 
   13442           35 :   do_pending_stack_adjust ();
   13443              : 
   13444           35 :   location_t loc = gimple_location (stmt);
   13445           35 :   struct separate_ops ops;
   13446           35 :   ops.code = TRUNC_MOD_EXPR;
   13447           35 :   ops.location = loc;
   13448           35 :   ops.type = TREE_TYPE (treeop0);
   13449           35 :   ops.op0 = treeop0;
   13450           35 :   ops.op1 = treeop1;
   13451           35 :   ops.op2 = NULL_TREE;
   13452           35 :   start_sequence ();
   13453           35 :   rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13454              :                                 EXPAND_NORMAL);
   13455           35 :   rtx_insn *moinsns = end_sequence ();
   13456              : 
   13457           35 :   unsigned mocost = seq_cost (moinsns, speed_p);
   13458           35 :   mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
   13459           35 :   mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
   13460              : 
   13461           35 :   ops.code = BIT_AND_EXPR;
   13462           35 :   ops.location = loc;
   13463           35 :   ops.type = TREE_TYPE (treeop0);
   13464           35 :   ops.op0 = treeop0;
   13465           35 :   ops.op1 = c3;
   13466           35 :   ops.op2 = NULL_TREE;
   13467           35 :   start_sequence ();
   13468           35 :   rtx mur = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13469              :                                 EXPAND_NORMAL);
   13470           35 :   rtx_insn *muinsns = end_sequence ();
   13471              : 
   13472           35 :   unsigned mucost = seq_cost (muinsns, speed_p);
   13473           35 :   mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
   13474           35 :   mucost += rtx_cost (expand_normal (c4), mode, EQ, 1, speed_p);
   13475              : 
   13476           35 :   if (mocost <= mucost)
   13477              :     {
   13478            0 :       emit_insn (moinsns);
   13479            0 :       *arg0 = make_tree (TREE_TYPE (*arg0), mor);
   13480            0 :       return code;
   13481              :     }
   13482              : 
   13483           35 :   emit_insn (muinsns);
   13484           35 :   *arg0 = make_tree (TREE_TYPE (*arg0), mur);
   13485           35 :   *arg1 = c4;
   13486           35 :   return code;
   13487           35 : }
   13488              : 
   13489              : /* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
   13490              :    If C1 is odd to:
   13491              :    (X - C2) * C3 <= C4 (or >), where
   13492              :    C3 is modular multiplicative inverse of C1 and 1<<prec and
   13493              :    C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
   13494              :    if C2 > ((1<<prec) - 1) % C1).
   13495              :    If C1 is even, S = ctz (C1) and C2 is 0, use
   13496              :    ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
   13497              :    inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
   13498              : 
   13499              :    For signed (X % C1) == 0 if C1 is odd to (all operations in it
   13500              :    unsigned):
   13501              :    (X * C3) + C4 <= 2 * C4, where
   13502              :    C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
   13503              :    C4 is ((1<<(prec - 1) - 1) / C1).
   13504              :    If C1 is even, S = ctz(C1), use
   13505              :    ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
   13506              :    where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
   13507              :    and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
   13508              : 
   13509              :    See the Hacker's Delight book, section 10-17.  */
   13510              : enum tree_code
   13511      3283692 : maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
   13512              : {
   13513      3283692 :   gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
   13514      3283692 :   gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
   13515              : 
   13516      3283692 :   if (optimize < 2)
   13517              :     return code;
   13518              : 
   13519      2489843 :   gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
   13520      2489843 :   if (stmt == NULL)
   13521              :     return code;
   13522              : 
   13523         2410 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13524         2410 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13525         2410 :   if (TREE_CODE (treeop0) != SSA_NAME
   13526         2308 :       || TREE_CODE (treeop1) != INTEGER_CST
   13527              :       /* Don't optimize the undefined behavior case x % 0;
   13528              :          x % 1 should have been optimized into zero, punt if
   13529              :          it makes it here for whatever reason;
   13530              :          x % -c should have been optimized into x % c.  */
   13531         1951 :       || compare_tree_int (treeop1, 2) <= 0
   13532              :       /* Likewise x % c == d where d >= c should be always false.  */
   13533         4285 :       || tree_int_cst_le (treeop1, *arg1))
   13534          535 :     return code;
   13535              : 
   13536              :   /* Unsigned x % pow2 is handled right already, for signed
   13537              :      modulo handle it in maybe_optimize_pow2p_mod_cmp.  */
   13538         1875 :   if (integer_pow2p (treeop1))
   13539           35 :     return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
   13540              : 
   13541         1840 :   tree type = TREE_TYPE (*arg0);
   13542         1840 :   scalar_int_mode mode;
   13543      3283664 :   if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
   13544              :     return code;
   13545         3680 :   if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
   13546         1840 :       || TYPE_PRECISION (type) <= 1)
   13547              :     return code;
   13548              : 
   13549         1840 :   signop sgn = UNSIGNED;
   13550              :   /* If both operands are known to have the sign bit clear, handle
   13551              :      even the signed modulo case as unsigned.  treeop1 is always
   13552              :      positive >= 2, checked above.  */
   13553         1840 :   if (!TYPE_UNSIGNED (type)
   13554         1840 :       && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) != 1)
   13555              :     sgn = SIGNED;
   13556              : 
   13557         1840 :   if (!TYPE_UNSIGNED (type))
   13558              :     {
   13559         1612 :       if (tree_int_cst_sgn (*arg1) == -1)
   13560              :         return code;
   13561         1605 :       type = unsigned_type_for (type);
   13562         1605 :       if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
   13563            0 :         return code;
   13564              :     }
   13565              : 
   13566         1833 :   int prec = TYPE_PRECISION (type);
   13567         1833 :   wide_int w = wi::to_wide (treeop1);
   13568         1833 :   int shift = wi::ctz (w);
   13569              :   /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
   13570              :      C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
   13571              :      If C1 is odd, we can handle all cases by subtracting
   13572              :      C4 below.  We could handle even the even C1 and C2 > -1U % C1 cases
   13573              :      e.g. by testing for overflow on the subtraction, punt on that for now
   13574              :      though.  */
   13575         1833 :   if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
   13576              :     {
   13577          191 :       if (sgn == SIGNED)
   13578          176 :         return code;
   13579           26 :       wide_int x = wi::umod_trunc (wi::mask (prec, false, prec), w);
   13580           26 :       if (wi::gtu_p (wi::to_wide (*arg1), x))
   13581           11 :         return code;
   13582           26 :     }
   13583              : 
   13584         1657 :   imm_use_iterator imm_iter;
   13585         1657 :   use_operand_p use_p;
   13586        12115 :   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
   13587              :     {
   13588         8813 :       gimple *use_stmt = USE_STMT (use_p);
   13589              :       /* Punt if treeop0 is used in the same bb in a division
   13590              :          or another modulo with the same divisor.  We should expect
   13591              :          the division and modulo combined together.  */
   13592        17217 :       if (use_stmt == stmt
   13593         8813 :           || gimple_bb (use_stmt) != gimple_bb (stmt))
   13594         8404 :         continue;
   13595          409 :       if (!is_gimple_assign (use_stmt)
   13596          409 :           || (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR
   13597          391 :               && gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR))
   13598          388 :         continue;
   13599           21 :       if (gimple_assign_rhs1 (use_stmt) != treeop0
   13600           21 :           || !operand_equal_p (gimple_assign_rhs2 (use_stmt), treeop1, 0))
   13601            9 :         continue;
   13602           12 :       return code;
   13603           12 :     }
   13604              : 
   13605         1645 :   w = wi::lrshift (w, shift);
   13606         1645 :   wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
   13607         1645 :   wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
   13608         1645 :   wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
   13609         1645 :   tree c3 = wide_int_to_tree (type, m);
   13610         1645 :   tree c5 = NULL_TREE;
   13611         1645 :   wide_int d, e;
   13612         1645 :   if (sgn == UNSIGNED)
   13613              :     {
   13614         1054 :       d = wi::divmod_trunc (wi::mask (prec, false, prec), w, UNSIGNED, &e);
   13615              :       /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
   13616              :          otherwise use < or subtract one from C4.  E.g. for
   13617              :          x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
   13618              :          x % 3U == 1 already needs to be
   13619              :          (x - 1) * 0xaaaaaaabU <= 0x55555554.  */
   13620         1054 :       if (!shift && wi::gtu_p (wi::to_wide (*arg1), e))
   13621           15 :         d -= 1;
   13622         1054 :       if (shift)
   13623          442 :         d = wi::lrshift (d, shift);
   13624              :     }
   13625              :   else
   13626              :     {
   13627          591 :       e = wi::udiv_trunc (wi::mask (prec - 1, false, prec), w);
   13628          591 :       if (!shift)
   13629          400 :         d = wi::lshift (e, 1);
   13630              :       else
   13631              :         {
   13632          191 :           e = wi::bit_and (e, wi::mask (shift, true, prec));
   13633          191 :           d = wi::lrshift (e, shift - 1);
   13634              :         }
   13635          591 :       c5 = wide_int_to_tree (type, e);
   13636              :     }
   13637         1645 :   tree c4 = wide_int_to_tree (type, d);
   13638              : 
   13639         1645 :   rtx op0 = expand_normal (treeop0);
   13640         1645 :   treeop0 = make_tree (TREE_TYPE (treeop0), op0);
   13641              : 
   13642         1645 :   bool speed_p = optimize_insn_for_speed_p ();
   13643              : 
   13644         1645 :   do_pending_stack_adjust ();
   13645              : 
   13646         1645 :   location_t loc = gimple_location (stmt);
   13647         1645 :   struct separate_ops ops;
   13648         1645 :   ops.code = TRUNC_MOD_EXPR;
   13649         1645 :   ops.location = loc;
   13650         1645 :   ops.type = TREE_TYPE (treeop0);
   13651         1645 :   ops.op0 = treeop0;
   13652         1645 :   ops.op1 = treeop1;
   13653         1645 :   ops.op2 = NULL_TREE;
   13654         1645 :   start_sequence ();
   13655         1645 :   rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13656              :                                 EXPAND_NORMAL);
   13657         1645 :   rtx_insn *moinsns = end_sequence ();
   13658              : 
   13659         1645 :   unsigned mocost = seq_cost (moinsns, speed_p);
   13660         1645 :   mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
   13661         1645 :   mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
   13662              : 
   13663         1645 :   tree t = fold_convert_loc (loc, type, treeop0);
   13664         1645 :   if (!integer_zerop (*arg1))
   13665           36 :     t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
   13666         1645 :   t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
   13667         1645 :   if (sgn == SIGNED)
   13668          591 :     t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
   13669         1645 :   if (shift)
   13670              :     {
   13671          633 :       tree s = build_int_cst (NULL_TREE, shift);
   13672          633 :       t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
   13673              :     }
   13674              : 
   13675         1645 :   start_sequence ();
   13676         1645 :   rtx mur = expand_normal (t);
   13677         1645 :   rtx_insn *muinsns = end_sequence ();
   13678              : 
   13679         1645 :   unsigned mucost = seq_cost (muinsns, speed_p);
   13680         1645 :   mucost += rtx_cost (mur, mode, LE, 0, speed_p);
   13681         1645 :   mucost += rtx_cost (expand_normal (c4), mode, LE, 1, speed_p);
   13682              : 
   13683         1645 :   if (mocost <= mucost)
   13684              :     {
   13685          264 :       emit_insn (moinsns);
   13686          264 :       *arg0 = make_tree (TREE_TYPE (*arg0), mor);
   13687          264 :       return code;
   13688              :     }
   13689              : 
   13690         1381 :   emit_insn (muinsns);
   13691         1381 :   *arg0 = make_tree (type, mur);
   13692         1381 :   *arg1 = c4;
   13693         1381 :   return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
   13694         3478 : }
   13695              : 
   13696              : /* Optimize x - y < 0 into x < 0 if x - y has undefined overflow.  */
   13697              : 
   13698              : void
   13699       237245 : maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
   13700              : {
   13701       237245 :   gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
   13702              :                        || code == LT_EXPR || code == LE_EXPR);
   13703       237245 :   gcc_checking_assert (integer_zerop (*arg1));
   13704              : 
   13705       237245 :   if (!optimize)
   13706              :     return;
   13707              : 
   13708       204237 :   gimple *stmt = get_def_for_expr (*arg0, MINUS_EXPR);
   13709       204237 :   if (stmt == NULL)
   13710              :     return;
   13711              : 
   13712         1353 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13713         1353 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13714         1353 :   if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
   13715              :     return;
   13716              : 
   13717         1256 :   if (issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_COMPARISON))
   13718            1 :     warning_at (gimple_location (stmt), OPT_Wstrict_overflow,
   13719              :                 "assuming signed overflow does not occur when "
   13720              :                 "simplifying %<X - Y %s 0%> to %<X %s Y%>",
   13721              :                 op_symbol_code (code), op_symbol_code (code));
   13722              : 
   13723         1256 :   *arg0 = treeop0;
   13724         1256 :   *arg1 = treeop1;
   13725              : }
   13726              : 
   13727              : 
   13728              : /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
   13729              :    a single bit equality/inequality test, returns where the result is located.  */
   13730              : 
   13731              : static rtx
   13732        10076 : expand_single_bit_test (location_t loc, enum tree_code code,
   13733              :                         tree inner, int bitnum,
   13734              :                         tree result_type, rtx target,
   13735              :                         machine_mode mode)
   13736              : {
   13737        10076 :   gcc_assert (code == NE_EXPR || code == EQ_EXPR);
   13738              : 
   13739        10076 :   tree type = TREE_TYPE (inner);
   13740        10076 :   scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
   13741        10076 :   int ops_unsigned;
   13742        10076 :   tree signed_type, unsigned_type, intermediate_type;
   13743        10076 :   gimple *inner_def;
   13744              : 
   13745              :   /* First, see if we can fold the single bit test into a sign-bit
   13746              :      test.  */
   13747        10076 :   if (bitnum == TYPE_PRECISION (type) - 1
   13748        10076 :       && type_has_mode_precision_p (type))
   13749              :     {
   13750          231 :       tree stype = signed_type_for (type);
   13751          428 :       tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
   13752              :                                   result_type,
   13753              :                                   fold_convert_loc (loc, stype, inner),
   13754              :                                   build_int_cst (stype, 0));
   13755          231 :       return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
   13756              :     }
   13757              : 
   13758              :   /* Otherwise we have (A & C) != 0 where C is a single bit,
   13759              :      convert that into ((A >> C2) & 1).  Where C2 = log2(C).
   13760              :      Similarly for (A & C) == 0.  */
   13761              : 
   13762              :   /* If INNER is a right shift of a constant and it plus BITNUM does
   13763              :      not overflow, adjust BITNUM and INNER.  */
   13764         9845 :   if ((inner_def = get_def_for_expr (inner, RSHIFT_EXPR))
   13765           85 :        && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
   13766            8 :        && bitnum < TYPE_PRECISION (type)
   13767         9853 :        && wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (inner_def)),
   13768         9845 :                      TYPE_PRECISION (type) - bitnum))
   13769              :     {
   13770            8 :       bitnum += tree_to_uhwi (gimple_assign_rhs2 (inner_def));
   13771            8 :       inner = gimple_assign_rhs1 (inner_def);
   13772              :     }
   13773              : 
   13774              :   /* If we are going to be able to omit the AND below, we must do our
   13775              :      operations as unsigned.  If we must use the AND, we have a choice.
   13776              :      Normally unsigned is faster, but for some machines signed is.  */
   13777         9845 :   ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
   13778              :                   && !flag_syntax_only) ? 0 : 1;
   13779              : 
   13780         9845 :   signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
   13781         9845 :   unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
   13782         9845 :   intermediate_type = ops_unsigned ? unsigned_type : signed_type;
   13783         9845 :   inner = fold_convert_loc (loc, intermediate_type, inner);
   13784              : 
   13785         9845 :   rtx inner0 = expand_expr (inner, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   13786              : 
   13787         9845 :   if (CONST_SCALAR_INT_P (inner0))
   13788              :     {
   13789            0 :       wide_int t = rtx_mode_t (inner0, operand_mode);
   13790            0 :       bool setp = (wi::lrshift (t, bitnum) & 1) != 0;
   13791            0 :       return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
   13792            0 :     }
   13793         9845 :   int bitpos = bitnum;
   13794              : 
   13795         9845 :   if (BYTES_BIG_ENDIAN)
   13796              :     bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
   13797              : 
   13798         9845 :   inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
   13799              :                               operand_mode, mode, 0, NULL);
   13800              : 
   13801         9845 :   if (code == EQ_EXPR)
   13802         3384 :     inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
   13803              :                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
   13804         9845 :   if (GET_MODE (inner0) != mode)
   13805              :     {
   13806            0 :       rtx t = gen_reg_rtx (mode);
   13807            0 :       convert_move (t, inner0, 0);
   13808            0 :       return t;
   13809              :     }
   13810              :   return inner0;
   13811              : }
   13812              : 
   13813              : /* Generate code to calculate OPS, and exploded expression
   13814              :    using a store-flag instruction and return an rtx for the result.
   13815              :    OPS reflects a comparison.
   13816              : 
   13817              :    If TARGET is nonzero, store the result there if convenient.
   13818              : 
   13819              :    Return zero if there is no suitable set-flag instruction
   13820              :    available on this machine.
   13821              : 
   13822              :    Once expand_expr has been called on the arguments of the comparison,
   13823              :    we are committed to doing the store flag, since it is not safe to
   13824              :    re-evaluate the expression.  We emit the store-flag insn by calling
   13825              :    emit_store_flag, but only expand the arguments if we have a reason
   13826              :    to believe that emit_store_flag will be successful.  If we think that
   13827              :    it will, but it isn't, we have to simulate the store-flag with a
   13828              :    set/jump/set sequence.  */
   13829              : 
   13830              : static rtx
   13831       589043 : do_store_flag (const_sepops ops, rtx target, machine_mode mode)
   13832              : {
   13833       589043 :   enum rtx_code code;
   13834       589043 :   tree arg0, arg1, type;
   13835       589043 :   machine_mode operand_mode;
   13836       589043 :   int unsignedp;
   13837       589043 :   rtx op0, op1;
   13838       589043 :   rtx subtarget = target;
   13839       589043 :   location_t loc = ops->location;
   13840       589043 :   unsigned HOST_WIDE_INT nunits;
   13841              : 
   13842       589043 :   arg0 = ops->op0;
   13843       589043 :   arg1 = ops->op1;
   13844              : 
   13845              :   /* Don't crash if the comparison was erroneous.  */
   13846       589043 :   if (arg0 == error_mark_node || arg1 == error_mark_node)
   13847            0 :     return const0_rtx;
   13848              : 
   13849       589043 :   type = TREE_TYPE (arg0);
   13850       589043 :   operand_mode = TYPE_MODE (type);
   13851       589043 :   unsignedp = TYPE_UNSIGNED (type);
   13852              : 
   13853              :   /* We won't bother with BLKmode store-flag operations because it would mean
   13854              :      passing a lot of information to emit_store_flag.  */
   13855       589043 :   if (operand_mode == BLKmode)
   13856              :     return 0;
   13857              : 
   13858              :   /* We won't bother with store-flag operations involving function pointers
   13859              :      when function pointers must be canonicalized before comparisons.  */
   13860       589043 :   if (targetm.have_canonicalize_funcptr_for_compare ()
   13861       589043 :       && ((POINTER_TYPE_P (TREE_TYPE (arg0))
   13862            0 :            && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
   13863            0 :           || (POINTER_TYPE_P (TREE_TYPE (arg1))
   13864            0 :               && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
   13865              :     return 0;
   13866              : 
   13867       589043 :   STRIP_NOPS (arg0);
   13868       589043 :   STRIP_NOPS (arg1);
   13869              : 
   13870              :   /* For vector typed comparisons emit code to generate the desired
   13871              :      all-ones or all-zeros mask.  */
   13872       589043 :   if (VECTOR_TYPE_P (ops->type))
   13873              :     {
   13874        22755 :       tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
   13875        22755 :       if (VECTOR_BOOLEAN_TYPE_P (ops->type)
   13876        45510 :           && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
   13877        22755 :         return expand_vec_cmp_expr (ops->type, ifexp, target);
   13878              :       else
   13879            0 :         gcc_unreachable ();
   13880              :     }
   13881              : 
   13882              :   /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
   13883              :      into (x - C2) * C3 < C4.  */
   13884       566288 :   if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
   13885       375712 :       && TREE_CODE (arg0) == SSA_NAME
   13886       375176 :       && TREE_CODE (arg1) == INTEGER_CST)
   13887              :     {
   13888       216961 :       enum tree_code new_code = maybe_optimize_mod_cmp (ops->code,
   13889              :                                                         &arg0, &arg1);
   13890       216961 :       if (new_code != ops->code)
   13891              :         {
   13892           92 :           struct separate_ops nops = *ops;
   13893           92 :           nops.code = new_code;
   13894           92 :           nops.op0 = arg0;
   13895           92 :           nops.op1 = arg1;
   13896           92 :           nops.type = TREE_TYPE (arg0);
   13897           92 :           return do_store_flag (&nops, target, mode);
   13898              :         }
   13899              :     }
   13900              : 
   13901              :   /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow.  */
   13902       566196 :   if (!unsignedp
   13903       403492 :       && (ops->code == LT_EXPR || ops->code == LE_EXPR
   13904       403492 :           || ops->code == GT_EXPR || ops->code == GE_EXPR)
   13905       121479 :       && integer_zerop (arg1)
   13906       604064 :       && TREE_CODE (arg0) == SSA_NAME)
   13907        37864 :     maybe_optimize_sub_cmp_0 (ops->code, &arg0, &arg1);
   13908              : 
   13909              :   /* Get the rtx comparison code to use.  We know that EXP is a comparison
   13910              :      operation of some type.  Some comparisons against 1 and -1 can be
   13911              :      converted to comparisons with zero.  Do so here so that the tests
   13912              :      below will be aware that we have a comparison with zero.   These
   13913              :      tests will not catch constants in the first operand, but constants
   13914              :      are rarely passed as the first operand.  */
   13915              : 
   13916       566196 :   switch (ops->code)
   13917              :     {
   13918              :     case EQ_EXPR:
   13919              :       code = EQ;
   13920              :       break;
   13921       225183 :     case NE_EXPR:
   13922       225183 :       code = NE;
   13923       225183 :       break;
   13924        38157 :     case LT_EXPR:
   13925        38157 :       if (integer_onep (arg1))
   13926            0 :         arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
   13927              :       else
   13928        38157 :         code = unsignedp ? LTU : LT;
   13929              :       break;
   13930        32650 :     case LE_EXPR:
   13931        32650 :       if (! unsignedp && integer_all_onesp (arg1))
   13932            0 :         arg1 = integer_zero_node, code = LT;
   13933              :       else
   13934        32650 :         code = unsignedp ? LEU : LE;
   13935              :       break;
   13936        52279 :     case GT_EXPR:
   13937        52279 :       if (! unsignedp && integer_all_onesp (arg1))
   13938            0 :         arg1 = integer_zero_node, code = GE;
   13939              :       else
   13940        52279 :         code = unsignedp ? GTU : GT;
   13941              :       break;
   13942        43996 :     case GE_EXPR:
   13943        43996 :       if (integer_onep (arg1))
   13944        28514 :         arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
   13945              :       else
   13946        43996 :         code = unsignedp ? GEU : GE;
   13947              :       break;
   13948              : 
   13949          676 :     case UNORDERED_EXPR:
   13950          676 :       code = UNORDERED;
   13951          676 :       break;
   13952          678 :     case ORDERED_EXPR:
   13953          678 :       code = ORDERED;
   13954          678 :       break;
   13955          482 :     case UNLT_EXPR:
   13956          482 :       code = UNLT;
   13957          482 :       break;
   13958        10782 :     case UNLE_EXPR:
   13959        10782 :       code = UNLE;
   13960        10782 :       break;
   13961          841 :     case UNGT_EXPR:
   13962          841 :       code = UNGT;
   13963          841 :       break;
   13964         9818 :     case UNGE_EXPR:
   13965         9818 :       code = UNGE;
   13966         9818 :       break;
   13967          141 :     case UNEQ_EXPR:
   13968          141 :       code = UNEQ;
   13969          141 :       break;
   13970           76 :     case LTGT_EXPR:
   13971           76 :       code = LTGT;
   13972           76 :       break;
   13973              : 
   13974            0 :     default:
   13975            0 :       gcc_unreachable ();
   13976              :     }
   13977              : 
   13978              :   /* Put a constant second.  */
   13979       566196 :   if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
   13980       564680 :       || TREE_CODE (arg0) == FIXED_CST)
   13981              :     {
   13982         1516 :       std::swap (arg0, arg1);
   13983         1516 :       code = swap_condition (code);
   13984              :     }
   13985              : 
   13986              :   /* If this is an equality or inequality test of a single bit, we can
   13987              :      do this by shifting the bit being tested to the low-order bit and
   13988              :      masking the result with the constant 1.  If the condition was EQ,
   13989              :      we xor it with 1.  This does not require an scc insn and is faster
   13990              :      than an scc insn even if we have it.  */
   13991              : 
   13992       566196 :   if ((code == NE || code == EQ)
   13993       375620 :       && (integer_zerop (arg1)
   13994       227290 :           || integer_pow2p (arg1))
   13995              :       /* vector types are not handled here. */
   13996       177710 :       && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE
   13997       743893 :       && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
   13998              :     {
   13999       177697 :       tree narg0 = arg0;
   14000       177697 :       wide_int nz = tree_nonzero_bits (narg0);
   14001       177697 :       gimple *srcstmt = get_def_for_expr (narg0, BIT_AND_EXPR);
   14002              :       /* If the defining statement was (x & POW2), then use that instead of
   14003              :          the non-zero bits.  */
   14004       177697 :       if (srcstmt && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
   14005              :         {
   14006         5737 :           nz = wi::to_wide (gimple_assign_rhs2 (srcstmt));
   14007         5737 :           narg0 = gimple_assign_rhs1 (srcstmt);
   14008              :         }
   14009              : 
   14010       177697 :       if (wi::popcount (nz) == 1
   14011       177697 :           && (integer_zerop (arg1)
   14012       167653 :               || wi::to_wide (arg1) == nz))
   14013              :         {
   14014        10076 :           int bitnum = wi::exact_log2 (nz);
   14015        10076 :           enum tree_code tcode = EQ_EXPR;
   14016        10076 :           if ((code == NE) ^ !integer_zerop (arg1))
   14017         6658 :             tcode = NE_EXPR;
   14018              : 
   14019        10076 :           type = lang_hooks.types.type_for_mode (mode, unsignedp);
   14020        10076 :           return expand_single_bit_test (loc, tcode,
   14021              :                                          narg0,
   14022              :                                          bitnum, type, target, mode);
   14023              :         }
   14024       177697 :     }
   14025              : 
   14026              : 
   14027       556120 :   if (! get_subtarget (target)
   14028       556120 :       || GET_MODE (subtarget) != operand_mode)
   14029              :     subtarget = 0;
   14030              : 
   14031       556120 :   expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
   14032              : 
   14033              :   /* For boolean vectors with less than mode precision
   14034              :      make sure to fill padding with consistent values.  */
   14035           13 :   if (VECTOR_BOOLEAN_TYPE_P (type)
   14036            0 :       && SCALAR_INT_MODE_P (operand_mode)
   14037       556120 :       && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
   14038       556120 :       && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
   14039              :     {
   14040            0 :       gcc_assert (code == EQ || code == NE);
   14041            0 :       op0 = expand_binop (mode, and_optab, op0,
   14042            0 :                           GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
   14043              :                           NULL_RTX, true, OPTAB_WIDEN);
   14044            0 :       op1 = expand_binop (mode, and_optab, op1,
   14045              :                           GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
   14046              :                           NULL_RTX, true, OPTAB_WIDEN);
   14047              :     }
   14048              : 
   14049       556120 :   if (target == 0)
   14050       369994 :     target = gen_reg_rtx (mode);
   14051              : 
   14052              :   /* Try a cstore if possible.  */
   14053       556120 :   return emit_store_flag_force (target, code, op0, op1,
   14054              :                                 operand_mode, unsignedp,
   14055       556120 :                                 (TYPE_PRECISION (ops->type) == 1
   14056      1111607 :                                  && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
   14057              : }
   14058              : 
   14059              : /* Attempt to generate a casesi instruction.  Returns true if successful,
   14060              :    false otherwise (i.e. if there is no casesi instruction).
   14061              : 
   14062              :    DEFAULT_PROBABILITY is the probability of jumping to the default
   14063              :    label.  */
   14064              : bool
   14065         8028 : try_casesi (tree index_type, tree index_expr, tree minval, tree range,
   14066              :             rtx table_label, rtx default_label, rtx fallback_label,
   14067              :             profile_probability default_probability)
   14068              : {
   14069         8028 :   class expand_operand ops[5];
   14070         8028 :   scalar_int_mode index_mode = SImode;
   14071         8028 :   rtx op1, op2, index;
   14072              : 
   14073         8028 :   if (! targetm.have_casesi ())
   14074              :     return false;
   14075              : 
   14076              :   /* The index must be some form of integer.  Convert it to SImode.  */
   14077            0 :   scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
   14078            0 :   if (GET_MODE_BITSIZE (omode) > GET_MODE_BITSIZE (index_mode))
   14079              :     {
   14080            0 :       rtx rangertx = expand_normal (range);
   14081              : 
   14082              :       /* We must handle the endpoints in the original mode.  */
   14083            0 :       index_expr = build2 (MINUS_EXPR, index_type,
   14084              :                            index_expr, minval);
   14085            0 :       minval = integer_zero_node;
   14086            0 :       index = expand_normal (index_expr);
   14087            0 :       if (default_label)
   14088            0 :         emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
   14089              :                                  omode, 1, default_label,
   14090              :                                  default_probability);
   14091              :       /* Now we can safely truncate.  */
   14092            0 :       index = convert_to_mode (index_mode, index, 0);
   14093              :     }
   14094              :   else
   14095              :     {
   14096            0 :       if (omode != index_mode)
   14097              :         {
   14098            0 :           index_type = lang_hooks.types.type_for_mode (index_mode, 0);
   14099            0 :           index_expr = fold_convert (index_type, index_expr);
   14100              :         }
   14101              : 
   14102            0 :       index = expand_normal (index_expr);
   14103              :     }
   14104              : 
   14105            0 :   do_pending_stack_adjust ();
   14106              : 
   14107            0 :   op1 = expand_normal (minval);
   14108            0 :   op2 = expand_normal (range);
   14109              : 
   14110            0 :   create_input_operand (&ops[0], index, index_mode);
   14111            0 :   create_convert_operand_from_type (&ops[1], op1, TREE_TYPE (minval));
   14112            0 :   create_convert_operand_from_type (&ops[2], op2, TREE_TYPE (range));
   14113            0 :   create_fixed_operand (&ops[3], table_label);
   14114            0 :   create_fixed_operand (&ops[4], (default_label
   14115              :                                   ? default_label
   14116              :                                   : fallback_label));
   14117            0 :   expand_jump_insn (targetm.code_for_casesi, 5, ops);
   14118            0 :   return true;
   14119              : }
   14120              : 
   14121              : /* Attempt to generate a tablejump instruction; same concept.  */
   14122              : /* Subroutine of the next function.
   14123              : 
   14124              :    INDEX is the value being switched on, with the lowest value
   14125              :    in the table already subtracted.
   14126              :    MODE is its expected mode (needed if INDEX is constant).
   14127              :    RANGE is the length of the jump table.
   14128              :    TABLE_LABEL is a CODE_LABEL rtx for the table itself.
   14129              : 
   14130              :    DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
   14131              :    index value is out of range.
   14132              :    DEFAULT_PROBABILITY is the probability of jumping to
   14133              :    the default label.  */
   14134              : 
   14135              : static void
   14136         8028 : do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
   14137              :               rtx default_label, profile_probability default_probability)
   14138              : {
   14139         8028 :   rtx temp, vector;
   14140              : 
   14141         8028 :   if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
   14142         6207 :     cfun->cfg->max_jumptable_ents = INTVAL (range);
   14143              : 
   14144              :   /* Do an unsigned comparison (in the proper mode) between the index
   14145              :      expression and the value which represents the length of the range.
   14146              :      Since we just finished subtracting the lower bound of the range
   14147              :      from the index expression, this comparison allows us to simultaneously
   14148              :      check that the original index expression value is both greater than
   14149              :      or equal to the minimum value of the range and less than or equal to
   14150              :      the maximum value of the range.  */
   14151              : 
   14152         8028 :   if (default_label)
   14153         4725 :     emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
   14154              :                              default_label, default_probability);
   14155              : 
   14156              :   /* If index is in range, it must fit in Pmode.
   14157              :      Convert to Pmode so we can index with it.  */
   14158         8998 :   if (mode != Pmode)
   14159              :     {
   14160         7036 :       unsigned int width;
   14161              : 
   14162              :       /* We know the value of INDEX is between 0 and RANGE.  If we have a
   14163              :          sign-extended subreg, and RANGE does not have the sign bit set, then
   14164              :          we have a value that is valid for both sign and zero extension.  In
   14165              :          this case, we get better code if we sign extend.  */
   14166         7036 :       if (GET_CODE (index) == SUBREG
   14167            9 :           && SUBREG_PROMOTED_VAR_P (index)
   14168            0 :           && SUBREG_PROMOTED_SIGNED_P (index)
   14169            0 :           && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode)))
   14170              :               <= HOST_BITS_PER_WIDE_INT)
   14171         7036 :           && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
   14172            0 :         index = convert_to_mode (Pmode, index, 0);
   14173              :       else
   14174         7036 :         index = convert_to_mode (Pmode, index, 1);
   14175              :     }
   14176              : 
   14177              :   /* Don't let a MEM slip through, because then INDEX that comes
   14178              :      out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
   14179              :      and break_out_memory_refs will go to work on it and mess it up.  */
   14180              : #ifdef PIC_CASE_VECTOR_ADDRESS
   14181              :   if (flag_pic && !REG_P (index))
   14182              :     index = copy_to_mode_reg (Pmode, index);
   14183              : #endif
   14184              : 
   14185              :   /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
   14186              :      GET_MODE_SIZE, because this indicates how large insns are.  The other
   14187              :      uses should all be Pmode, because they are addresses.  This code
   14188              :      could fail if addresses and insns are not the same size.  */
   14189         8998 :   index = simplify_gen_binary (MULT, Pmode, index,
   14190        16056 :                                gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
   14191         8028 :                                              Pmode));
   14192         8998 :   index = simplify_gen_binary (PLUS, Pmode, index,
   14193         8028 :                                gen_rtx_LABEL_REF (Pmode, table_label));
   14194              : 
   14195              : #ifdef PIC_CASE_VECTOR_ADDRESS
   14196              :   if (flag_pic)
   14197              :     index = PIC_CASE_VECTOR_ADDRESS (index);
   14198              :   else
   14199              : #endif
   14200         9507 :     index = memory_address (CASE_VECTOR_MODE, index);
   14201         9507 :   temp = gen_reg_rtx (CASE_VECTOR_MODE);
   14202         9507 :   vector = gen_const_mem (CASE_VECTOR_MODE, index);
   14203         8028 :   convert_move (temp, vector, 0);
   14204              : 
   14205         8028 :   emit_jump_insn (targetm.gen_tablejump (temp, table_label));
   14206              : 
   14207              :   /* If we are generating PIC code or if the table is PC-relative, the
   14208              :      table and JUMP_INSN must be adjacent, so don't output a BARRIER.  */
   14209         8028 :   if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
   14210         7048 :     emit_barrier ();
   14211         8028 : }
   14212              : 
   14213              : bool
   14214         8028 : try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
   14215              :                rtx table_label, rtx default_label,
   14216              :                profile_probability default_probability)
   14217              : {
   14218         8028 :   rtx index;
   14219              : 
   14220         8028 :   if (! targetm.have_tablejump ())
   14221              :     return false;
   14222              : 
   14223         8028 :   index_expr = fold_build2 (MINUS_EXPR, index_type,
   14224              :                             fold_convert (index_type, index_expr),
   14225              :                             fold_convert (index_type, minval));
   14226         8028 :   index = expand_normal (index_expr);
   14227         8028 :   do_pending_stack_adjust ();
   14228              : 
   14229         8028 :   do_tablejump (index, TYPE_MODE (index_type),
   14230         8028 :                 convert_modes (TYPE_MODE (index_type),
   14231         8028 :                                TYPE_MODE (TREE_TYPE (range)),
   14232              :                                expand_normal (range),
   14233         8028 :                                TYPE_UNSIGNED (TREE_TYPE (range))),
   14234              :                 table_label, default_label, default_probability);
   14235         8028 :   return true;
   14236              : }
   14237              : 
   14238              : /* Return a CONST_VECTOR rtx representing vector mask for
   14239              :    a VECTOR_CST of booleans.  */
   14240              : static rtx
   14241          724 : const_vector_mask_from_tree (tree exp)
   14242              : {
   14243          724 :   machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   14244          724 :   machine_mode inner = GET_MODE_INNER (mode);
   14245              : 
   14246          724 :   rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
   14247          724 :                               VECTOR_CST_NELTS_PER_PATTERN (exp));
   14248          724 :   unsigned int count = builder.encoded_nelts ();
   14249         3748 :   for (unsigned int i = 0; i < count; ++i)
   14250              :     {
   14251         3024 :       tree elt = VECTOR_CST_ELT (exp, i);
   14252         3024 :       gcc_assert (TREE_CODE (elt) == INTEGER_CST);
   14253         3024 :       if (integer_zerop (elt))
   14254         1191 :         builder.quick_push (CONST0_RTX (inner));
   14255         1833 :       else if (integer_onep (elt)
   14256         1833 :                || integer_minus_onep (elt))
   14257         1833 :         builder.quick_push (CONSTM1_RTX (inner));
   14258              :       else
   14259            0 :         gcc_unreachable ();
   14260              :     }
   14261          724 :   return builder.build ();
   14262          724 : }
   14263              : 
   14264              : /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
   14265              : static rtx
   14266       554091 : const_vector_from_tree (tree exp)
   14267              : {
   14268       554091 :   machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   14269              : 
   14270       554091 :   if (initializer_zerop (exp))
   14271       164727 :     return CONST0_RTX (mode);
   14272              : 
   14273       389364 :   if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
   14274          724 :     return const_vector_mask_from_tree (exp);
   14275              : 
   14276       388640 :   machine_mode inner = GET_MODE_INNER (mode);
   14277              : 
   14278       388640 :   rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
   14279       388640 :                               VECTOR_CST_NELTS_PER_PATTERN (exp));
   14280       388640 :   unsigned int count = builder.encoded_nelts ();
   14281      1257104 :   for (unsigned int i = 0; i < count; ++i)
   14282              :     {
   14283       868464 :       tree elt = VECTOR_CST_ELT (exp, i);
   14284       868464 :       if (TREE_CODE (elt) == REAL_CST)
   14285       132239 :         builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt),
   14286              :                                                           inner));
   14287       736225 :       else if (TREE_CODE (elt) == FIXED_CST)
   14288            0 :         builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
   14289              :                                                           inner));
   14290              :       else
   14291       736225 :         builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt),
   14292              :                                                   inner));
   14293              :     }
   14294       388640 :   return builder.build ();
   14295       388640 : }
   14296              : 
   14297              : /* Build a decl for a personality function given a language prefix.  */
   14298              : 
   14299              : tree
   14300        32016 : build_personality_function (const char *lang)
   14301              : {
   14302        32016 :   const char *unwind_and_version;
   14303        32016 :   tree decl, type;
   14304        32016 :   char *name;
   14305              : 
   14306        32016 :   switch (targetm_common.except_unwind_info (&global_options))
   14307              :     {
   14308              :     case UI_NONE:
   14309              :       return NULL;
   14310              :     case UI_SJLJ:
   14311              :       unwind_and_version = "_sj0";
   14312              :       break;
   14313        32016 :     case UI_DWARF2:
   14314        32016 :     case UI_TARGET:
   14315        32016 :       unwind_and_version = "_v0";
   14316        32016 :       break;
   14317            0 :     case UI_SEH:
   14318            0 :       unwind_and_version = "_seh0";
   14319            0 :       break;
   14320            0 :     default:
   14321            0 :       gcc_unreachable ();
   14322              :     }
   14323              : 
   14324        32016 :   name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
   14325              : 
   14326        32016 :   type = build_function_type_list (unsigned_type_node,
   14327              :                                    integer_type_node, integer_type_node,
   14328              :                                    long_long_unsigned_type_node,
   14329              :                                    ptr_type_node, ptr_type_node, NULL_TREE);
   14330        32016 :   decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
   14331              :                      get_identifier (name), type);
   14332        32016 :   DECL_ARTIFICIAL (decl) = 1;
   14333        32016 :   DECL_EXTERNAL (decl) = 1;
   14334        32016 :   TREE_PUBLIC (decl) = 1;
   14335              : 
   14336              :   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
   14337              :      are the flags assigned by targetm.encode_section_info.  */
   14338        32016 :   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
   14339              : 
   14340        32016 :   return decl;
   14341              : }
   14342              : 
   14343              : /* Extracts the personality function of DECL and returns the corresponding
   14344              :    libfunc.  */
   14345              : 
   14346              : rtx
   14347      1616975 : get_personality_function (tree decl)
   14348              : {
   14349      1616975 :   tree personality = DECL_FUNCTION_PERSONALITY (decl);
   14350      1616975 :   enum eh_personality_kind pk;
   14351              : 
   14352      1616975 :   pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
   14353      1616975 :   if (pk == eh_personality_none)
   14354              :     return NULL;
   14355              : 
   14356       152029 :   if (!personality
   14357       152029 :       && pk == eh_personality_any)
   14358        68335 :     personality = lang_hooks.eh_personality ();
   14359              : 
   14360       152029 :   if (pk == eh_personality_lang)
   14361        83694 :     gcc_assert (personality != NULL_TREE);
   14362              : 
   14363       152029 :   return XEXP (DECL_RTL (personality), 0);
   14364              : }
   14365              : 
   14366              : /* Returns a tree for the size of EXP in bytes.  */
   14367              : 
   14368              : static tree
   14369     14518359 : tree_expr_size (const_tree exp)
   14370              : {
   14371     14518359 :   if (DECL_P (exp)
   14372     14518359 :       && DECL_SIZE_UNIT (exp) != 0)
   14373      1932043 :     return DECL_SIZE_UNIT (exp);
   14374              :   else
   14375     12586316 :     return size_in_bytes (TREE_TYPE (exp));
   14376              : }
   14377              : 
   14378              : /* Return an rtx for the size in bytes of the value of EXP.  */
   14379              : 
   14380              : rtx
   14381     14332473 : expr_size (tree exp)
   14382              : {
   14383     14332473 :   tree size;
   14384              : 
   14385     14332473 :   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
   14386          773 :     size = TREE_OPERAND (exp, 1);
   14387              :   else
   14388              :     {
   14389     14331700 :       size = tree_expr_size (exp);
   14390     14331700 :       gcc_assert (size);
   14391     14331700 :       gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
   14392              :     }
   14393              : 
   14394     14332473 :   return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
   14395              : }
   14396              : 
   14397              : /* Return a wide integer for the size in bytes of the value of EXP, or -1
   14398              :    if the size can vary or is larger than an integer.  */
   14399              : 
   14400              : HOST_WIDE_INT
   14401       186659 : int_expr_size (const_tree exp)
   14402              : {
   14403       186659 :   tree size;
   14404              : 
   14405       186659 :   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
   14406            0 :     size = TREE_OPERAND (exp, 1);
   14407              :   else
   14408              :     {
   14409       186659 :       size = tree_expr_size (exp);
   14410       186659 :       gcc_assert (size);
   14411              :     }
   14412              : 
   14413       186659 :   if (size == 0 || !tree_fits_shwi_p (size))
   14414            0 :     return -1;
   14415              : 
   14416       186659 :   return tree_to_shwi (size);
   14417              : }
   14418              : 
   14419              : /* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
   14420              :    in GF (2^N).
   14421              :    Author: Richard Sandiford <richard.sandiford@arm.com>  */
   14422              : 
   14423              : unsigned HOST_WIDE_INT
   14424            0 : gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
   14425              :                              unsigned short n)
   14426              : {
   14427              :   /* The result has degree N, so needs N + 1 bits.  */
   14428            0 :   gcc_assert (n < 64);
   14429              : 
   14430              :   /* Perform a division step for the x^2N coefficient.  At this point the
   14431              :      quotient and remainder have N implicit trailing zeros.  */
   14432              :   unsigned HOST_WIDE_INT quotient = 1;
   14433              :   unsigned HOST_WIDE_INT remainder = polynomial;
   14434              : 
   14435              :   /* Process the coefficients for x^(2N-1) down to x^N, with each step
   14436              :      reducing the number of implicit trailing zeros by one.  */
   14437            0 :   for (unsigned int i = 0; i < n; ++i)
   14438              :     {
   14439            0 :       bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
   14440            0 :       quotient = (quotient << 1) | coeff;
   14441            0 :       remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
   14442              :     }
   14443            0 :   return quotient;
   14444              : }
   14445              : 
   14446              : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
   14447              :    CRC_BITS is CRC size.  */
   14448              : 
   14449              : static unsigned HOST_WIDE_INT
   14450        70400 : calculate_crc (unsigned HOST_WIDE_INT crc,
   14451              :                unsigned HOST_WIDE_INT polynomial,
   14452              :                unsigned short crc_bits)
   14453              : {
   14454        70400 :   unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
   14455        70400 :   crc = crc << (crc_bits - 8);
   14456       633600 :   for (short i = 8; i > 0; --i)
   14457              :     {
   14458       563200 :       if (crc & msb)
   14459       281600 :         crc = (crc << 1) ^ polynomial;
   14460              :       else
   14461       281600 :         crc <<= 1;
   14462              :     }
   14463              :   /* Zero out bits in crc beyond the specified number of crc_bits.  */
   14464        70400 :   if (crc_bits < sizeof (crc) * CHAR_BIT)
   14465        61952 :     crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
   14466        70400 :   return crc;
   14467              : }
   14468              : 
   14469              : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
   14470              :    POLYNOM is the polynomial used to calculate the CRC table's elements.
   14471              :    CRC_BITS is the size of CRC, may be 8, 16, ... . */
   14472              : 
   14473              : static rtx
   14474          275 : assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   14475              : {
   14476          275 :   unsigned table_el_n = 0x100;
   14477          275 :   tree ar = build_array_type (make_unsigned_type (crc_bits),
   14478          275 :                               build_index_type (size_int (table_el_n - 1)));
   14479              : 
   14480              :   /* Initialize the table.  */
   14481          275 :   vec<tree, va_gc> *initial_values;
   14482          275 :   vec_alloc (initial_values, table_el_n);
   14483        70675 :   for (size_t i = 0; i < table_el_n; ++i)
   14484              :     {
   14485        70400 :       unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
   14486        70400 :       tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
   14487        70400 :       vec_safe_push (initial_values, element);
   14488              :     }
   14489          275 :   tree ctor = build_constructor_from_vec (ar, initial_values);
   14490          275 :   rtx mem = output_constant_def (ctor, 1);
   14491          275 :   gcc_assert (MEM_P (mem));
   14492          275 :   if (dump_file && (dump_flags & TDF_DETAILS))
   14493              :     {
   14494           32 :       fprintf (dump_file,
   14495              :                ";; emitting crc table crc_%u_polynomial_"
   14496              :                HOST_WIDE_INT_PRINT_HEX " ",
   14497              :                crc_bits, polynom);
   14498           32 :       print_rtl_single (dump_file, XEXP (mem, 0));
   14499           32 :       fprintf (dump_file, "\n");
   14500              :     }
   14501              : 
   14502          275 :   return XEXP (mem, 0);
   14503              : }
   14504              : 
   14505              : /* Generate CRC lookup table by calculating CRC for all possible
   14506              :    8-bit data values.  The table is stored with a specific name in the read-only
   14507              :    static data section.
   14508              :    POLYNOM is the polynomial used to calculate the CRC table's elements.
   14509              :    CRC_BITS is the size of CRC, may be 8, 16, ... .  */
   14510              : 
   14511              : static rtx
   14512          275 : generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   14513              : {
   14514          275 :   gcc_assert (crc_bits <= 64);
   14515              : 
   14516          275 :   return assemble_crc_table (polynom, crc_bits);
   14517              : }
   14518              : 
   14519              : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
   14520              :    POLYNOMIAL (without leading 1).
   14521              : 
   14522              :    First, using POLYNOMIAL's value generates CRC table of 256 elements,
   14523              :    then generates the assembly for the following code,
   14524              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64, depending on CRC:
   14525              : 
   14526              :      for (int i = 0; i < data_bit_size / 8; i++)
   14527              :        crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
   14528              :                                     ^ (data >> (data_bit_size - (i + 1) * 8)
   14529              :                                     & 0xFF))];
   14530              : 
   14531              :    So to take values from the table, we need 8-bit data.
   14532              :    If input data size is not 8, then first we extract upper 8 bits,
   14533              :    then the other 8 bits, and so on.  */
   14534              : 
   14535              : static void
   14536          275 : calculate_table_based_CRC (rtx *crc, const rtx &input_data,
   14537              :                            const rtx &polynomial,
   14538              :                            machine_mode data_mode)
   14539              : {
   14540          275 :   machine_mode mode = GET_MODE (*crc);
   14541          275 :   unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
   14542          275 :   unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
   14543          275 :   rtx tab = generate_crc_table (UINTVAL (polynomial), crc_bit_size);
   14544              : 
   14545          762 :   for (unsigned short i = 0; i < data_size; i++)
   14546              :     {
   14547              :       /* crc >> (crc_bit_size - 8).  */
   14548          487 :       *crc = force_reg (mode, *crc);
   14549          487 :       rtx op1 = expand_shift (RSHIFT_EXPR, mode, *crc, crc_bit_size - 8,
   14550              :                               NULL_RTX, 1);
   14551              : 
   14552              :       /* data >> (8 * (GET_MODE_SIZE (data_mode).to_constant () - i - 1)).  */
   14553          487 :       unsigned range_8 = 8 * (data_size - i - 1);
   14554              :       /* CRC's mode is always at least as wide as INPUT_DATA.  Convert
   14555              :          INPUT_DATA into CRC's mode.  */
   14556          487 :       rtx data = gen_reg_rtx (mode);
   14557          487 :       convert_move (data, input_data, 1);
   14558          487 :       data = expand_shift (RSHIFT_EXPR, mode, data, range_8, NULL_RTX, 1);
   14559              : 
   14560              :       /* data >> (8 * (GET_MODE_SIZE (mode)
   14561              :                                         .to_constant () - i - 1)) & 0xFF.  */
   14562          487 :       rtx data_final = expand_and (mode, data,
   14563              :                                    gen_int_mode (255, mode), NULL_RTX);
   14564              : 
   14565              :       /* (crc >> (crc_bit_size - 8)) ^ data_8bit.  */
   14566          487 :       rtx in = expand_binop (mode, xor_optab, op1, data_final,
   14567              :                              NULL_RTX, 1, OPTAB_WIDEN);
   14568              : 
   14569              :       /* ((crc >> (crc_bit_size - 8)) ^ data_8bit) & 0xFF.  */
   14570          487 :       rtx index = expand_and (mode, in, gen_int_mode (255, mode),
   14571              :                               NULL_RTX);
   14572          974 :       int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
   14573          487 :       index = expand_shift (LSHIFT_EXPR, mode, index,
   14574          487 :                             log_crc_size, NULL_RTX, 0);
   14575              : 
   14576          505 :       rtx addr = gen_reg_rtx (Pmode);
   14577          487 :       convert_move (addr, index, 1);
   14578          505 :       addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
   14579              :                             0, OPTAB_DIRECT);
   14580              : 
   14581              :       /* crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit]  */
   14582          487 :       rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
   14583              : 
   14584              :       /* (crc << 8) if CRC is larger than 8, otherwise crc = 0.  */
   14585          487 :       rtx high = NULL_RTX;
   14586          487 :       if (crc_bit_size != 8)
   14587          448 :         high = expand_shift (LSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 0);
   14588              :       else
   14589           39 :         high = gen_int_mode (0, mode);
   14590              : 
   14591              :       /* crc = (crc << 8)
   14592              :                ^ crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit];  */
   14593          487 :       *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
   14594              :                            OPTAB_WIDEN);
   14595              :     }
   14596          275 : }
   14597              : 
   14598              : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
   14599              :    POLYNOMIAL (without leading 1).
   14600              : 
   14601              :    CRC is OP1, data is OP2 and the polynomial is OP3.
   14602              :    This must generate a CRC table and an assembly for the following code,
   14603              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
   14604              :    uint_crc_bit_size_t
   14605              :    crc_crc_bit_size (uint_crc_bit_size_t crc_init,
   14606              :                      uint_data_bit_size_t data, size_t size)
   14607              :    {
   14608              :      uint_crc_bit_size_t crc = crc_init;
   14609              :      for (int i = 0; i < data_bit_size / 8; i++)
   14610              :        crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
   14611              :                                     ^ (data >> (data_bit_size - (i + 1) * 8)
   14612              :                                     & 0xFF))];
   14613              :      return crc;
   14614              :    }  */
   14615              : 
   14616              : void
   14617          136 : expand_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
   14618              :                         machine_mode data_mode)
   14619              : {
   14620          136 :   gcc_assert (!CONST_INT_P (op0));
   14621          136 :   gcc_assert (CONST_INT_P (op3));
   14622          136 :   machine_mode crc_mode = GET_MODE (op0);
   14623          136 :   rtx crc = gen_reg_rtx (crc_mode);
   14624          136 :   convert_move (crc, op1, 0);
   14625          136 :   calculate_table_based_CRC (&crc, op2, op3, data_mode);
   14626          136 :   convert_move (op0, crc, 0);
   14627          136 : }
   14628              : 
   14629              : /* Generate the common operation for reflecting values:
   14630              :    *OP = (*OP & AND1_VALUE) << SHIFT_VAL | (*OP & AND2_VALUE) >> SHIFT_VAL;  */
   14631              : 
   14632              : void
   14633         1774 : gen_common_operation_to_reflect (rtx *op,
   14634              :                                  unsigned HOST_WIDE_INT and1_value,
   14635              :                                  unsigned HOST_WIDE_INT and2_value,
   14636              :                                  unsigned shift_val)
   14637              : {
   14638         1774 :   rtx op1 = expand_and (GET_MODE (*op), *op,
   14639         1774 :                         gen_int_mode (and1_value, GET_MODE (*op)), NULL_RTX);
   14640         1774 :   op1 = expand_shift (LSHIFT_EXPR, GET_MODE (*op), op1, shift_val, op1, 0);
   14641         1774 :   rtx op2 = expand_and (GET_MODE (*op), *op,
   14642         1774 :                         gen_int_mode (and2_value, GET_MODE (*op)), NULL_RTX);
   14643         1774 :   op2 = expand_shift (RSHIFT_EXPR, GET_MODE (*op), op2, shift_val, op2, 1);
   14644         1774 :   *op = expand_binop (GET_MODE (*op), ior_optab, op1,
   14645              :                       op2, *op, 0, OPTAB_LIB_WIDEN);
   14646         1774 : }
   14647              : 
   14648              : /* Reflect 64-bit value for the 64-bit target.  */
   14649              : 
   14650              : void
   14651           47 : reflect_64_bit_value (rtx *op)
   14652              : {
   14653           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00000000FFFFFFFF),
   14654              :                                    HOST_WIDE_INT_C (0xFFFFFFFF00000000), 32);
   14655           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF0000FFFF),
   14656              :                                    HOST_WIDE_INT_C (0xFFFF0000FFFF0000), 16);
   14657           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF00FF00FF),
   14658              :                                    HOST_WIDE_INT_C (0xFF00FF00FF00FF00), 8);
   14659           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F0F0F0F0F),
   14660              :                                    HOST_WIDE_INT_C (0xF0F0F0F0F0F0F0F0), 4);
   14661           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333333333333333),
   14662              :                                    HOST_WIDE_INT_C (0xCCCCCCCCCCCCCCCC), 2);
   14663           47 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555555555555555),
   14664              :                                    HOST_WIDE_INT_C (0xAAAAAAAAAAAAAAAA), 1);
   14665           47 : }
   14666              : 
   14667              : /* Reflect 32-bit value for the 32-bit target.  */
   14668              : 
   14669              : void
   14670          137 : reflect_32_bit_value (rtx *op)
   14671              : {
   14672          137 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF),
   14673              :                                   HOST_WIDE_INT_C (0xFFFF0000), 16);
   14674          137 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF),
   14675              :                                   HOST_WIDE_INT_C (0xFF00FF00), 8);
   14676          137 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F),
   14677              :                                    HOST_WIDE_INT_C (0xF0F0F0F0), 4);
   14678          137 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33333333),
   14679              :                                    HOST_WIDE_INT_C (0xCCCCCCCC), 2);
   14680          137 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55555555),
   14681              :                                    HOST_WIDE_INT_C (0xAAAAAAAA), 1);
   14682          137 : }
   14683              : 
   14684              : /* Reflect 16-bit value for the 16-bit target.  */
   14685              : 
   14686              : void
   14687          108 : reflect_16_bit_value (rtx *op)
   14688              : {
   14689          108 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF),
   14690              :                                    HOST_WIDE_INT_C (0xFF00), 8);
   14691          108 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F),
   14692              :                                    HOST_WIDE_INT_C (0xF0F0), 4);
   14693          108 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333),
   14694              :                                    HOST_WIDE_INT_C (0xCCCC), 2);
   14695          108 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555),
   14696              :                                    HOST_WIDE_INT_C (0xAAAA), 1);
   14697          108 : }
   14698              : 
   14699              : /* Reflect 8-bit value for the 8-bit target.  */
   14700              : 
   14701              : void
   14702          125 : reflect_8_bit_value (rtx *op)
   14703              : {
   14704          125 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F),
   14705              :                                    HOST_WIDE_INT_C (0xF0), 4);
   14706          125 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33),
   14707              :                                    HOST_WIDE_INT_C (0xCC), 2);
   14708          125 :   gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55),
   14709              :                                    HOST_WIDE_INT_C (0xAA), 1);
   14710          125 : }
   14711              : 
   14712              : /* Generate instruction sequence which reflects the value of the OP
   14713              :    using shift, and, or operations.  OP's mode may be less than word_mode.  */
   14714              : 
   14715              : void
   14716          417 : generate_reflecting_code_standard (rtx *op)
   14717              : {
   14718         1251 :   gcc_assert (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant ()  >= 8
   14719              :               && GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () <= 64);
   14720              : 
   14721          834 :   if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 64)
   14722           47 :     reflect_64_bit_value (op);
   14723          740 :   else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 32)
   14724          137 :     reflect_32_bit_value (op);
   14725          466 :   else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 16)
   14726          108 :     reflect_16_bit_value (op);
   14727              :   else
   14728          125 :     reflect_8_bit_value (op);
   14729          417 : }
   14730              : 
   14731              : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA and
   14732              :    the POLYNOMIAL (without leading 1).
   14733              : 
   14734              :    CRC is OP1, data is OP2 and the polynomial is OP3.
   14735              :    This must generate CRC table and assembly for the following code,
   14736              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
   14737              :    uint_crc_bit_size_t
   14738              :    crc_crc_bit_size (uint_crc_bit_size_t crc_init,
   14739              :                            uint_data_bit_size_t data, size_t size)
   14740              :    {
   14741              :      reflect (crc_init)
   14742              :      uint_crc_bit_size_t crc = crc_init;
   14743              :      reflect (data);
   14744              :      for (int i = 0; i < data_bit_size / 8; i++)
   14745              :        crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
   14746              :                           ^ (data >> (data_bit_size - (i + 1) * 8) & 0xFF))];
   14747              :      reflect (crc);
   14748              :      return crc;
   14749              :    }  */
   14750              : 
   14751              : void
   14752          139 : expand_reversed_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
   14753              :                                  machine_mode data_mode,
   14754              :                                  void (*gen_reflecting_code) (rtx *op))
   14755              : {
   14756          139 :   gcc_assert (!CONST_INT_P (op0));
   14757          139 :   gcc_assert (CONST_INT_P (op3));
   14758          139 :   machine_mode crc_mode = GET_MODE (op0);
   14759              : 
   14760          139 :   rtx crc = gen_reg_rtx (crc_mode);
   14761          139 :   convert_move (crc, op1, 0);
   14762          139 :   gen_reflecting_code (&crc);
   14763              : 
   14764          139 :   rtx data = gen_reg_rtx (data_mode);
   14765          139 :   convert_move (data, op2, 0);
   14766          139 :   gen_reflecting_code (&data);
   14767              : 
   14768          139 :   calculate_table_based_CRC (&crc, data, op3, data_mode);
   14769              : 
   14770          139 :   gen_reflecting_code (&crc);
   14771          139 :   convert_move (op0, crc, 0);
   14772          139 : }
        

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.