LCOV - code coverage report
Current view: top level - gcc - expr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.8 % 6952 5688
Test Date: 2026-09-19 16:22:48 Functions: 94.4 % 178 168
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 "tree-eh.h"
      68              : #include "flags.h"
      69              : #include "internal-fn.h"
      70              : #include "gimple-range.h"
      71              : 
      72              : 
      73              : /* If this is nonzero, we do not bother generating VOLATILE
      74              :    around volatile memory references, and we are willing to
      75              :    output indirect addresses.  If cse is to follow, we reject
      76              :    indirect addresses so a useful potential cse is generated;
      77              :    if it is used only once, instruction combination will produce
      78              :    the same indirect address eventually.  */
      79              : int cse_not_expected;
      80              : 
      81              : /* Cache of the "extended" flag in the target's _BitInt description
      82              :    for use during expand.  */
      83              : int bitint_extended = -1;
      84              : 
      85              : static bool block_move_libcall_safe_for_call_parm (void);
      86              : static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
      87              :                                          HOST_WIDE_INT, unsigned HOST_WIDE_INT,
      88              :                                          unsigned HOST_WIDE_INT,
      89              :                                          unsigned HOST_WIDE_INT, bool);
      90              : static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned, int);
      91              : static void emit_block_move_via_sized_loop (rtx, rtx, rtx, unsigned, unsigned);
      92              : static void emit_block_move_via_oriented_loop (rtx, rtx, rtx, unsigned, unsigned);
      93              : static rtx emit_block_cmp_via_loop (rtx, rtx, rtx, tree, rtx, bool,
      94              :                                     unsigned, unsigned);
      95              : static rtx_insn *compress_float_constant (rtx, rtx);
      96              : static rtx get_subtarget (rtx);
      97              : static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
      98              :                         machine_mode, tree, alias_set_type, bool, bool);
      99              : 
     100              : static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
     101              : 
     102              : static bool is_aligning_offset (const_tree, const_tree);
     103              : static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
     104              : static rtx do_store_flag (const_sepops, rtx, machine_mode);
     105              : #ifdef PUSH_ROUNDING
     106              : static void emit_single_push_insn (machine_mode, rtx, tree);
     107              : #endif
     108              : static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
     109              :                           profile_probability);
     110              : static rtx const_vector_from_tree (tree);
     111              : static tree tree_expr_size (const_tree);
     112              : static void convert_mode_scalar (rtx, rtx, int);
     113              : 
     114              : 
     115              : /* This is run to set up which modes can be used
     116              :    directly in memory and to initialize the block move optab.  It is run
     117              :    at the beginning of compilation and when the target is reinitialized.  */
     118              : 
     119              : void
     120       220100 : init_expr_target (void)
     121              : {
     122       220100 :   rtx pat;
     123       220100 :   int num_clobbers;
     124       220100 :   rtx mem, mem1;
     125       220100 :   rtx reg;
     126              : 
     127              :   /* Try indexing by frame ptr and try by stack ptr.
     128              :      It is known that on the Convex the stack ptr isn't a valid index.
     129              :      With luck, one or the other is valid on any machine.  */
     130       220100 :   mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
     131       220100 :   mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
     132              : 
     133              :   /* A scratch register we can modify in-place below to avoid
     134              :      useless RTL allocations.  */
     135       220100 :   reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
     136              : 
     137       220100 :   rtx_insn *insn = as_a<rtx_insn *> (rtx_alloc (INSN));
     138       220100 :   pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
     139       220100 :   PATTERN (insn) = pat;
     140              : 
     141     27512500 :   for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
     142     27292400 :        mode = (machine_mode) ((int) mode + 1))
     143              :     {
     144     27292400 :       int regno;
     145              : 
     146     27292400 :       direct_load[(int) mode] = direct_store[(int) mode] = 0;
     147     27292400 :       PUT_MODE (mem, mode);
     148     27292400 :       PUT_MODE (mem1, mode);
     149              : 
     150              :       /* See if there is some register that can be used in this mode and
     151              :          directly loaded or stored from memory.  */
     152              : 
     153     27292400 :       if (mode != VOIDmode && mode != BLKmode)
     154   1878494171 :         for (regno = 0; regno < FIRST_PSEUDO_REGISTER
     155   1905346371 :              && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
     156              :              regno++)
     157              :           {
     158   1878494171 :             if (!targetm.hard_regno_mode_ok (regno, mode))
     159   1752332939 :               continue;
     160              : 
     161    126161232 :             set_mode_and_regno (reg, mode, regno);
     162              : 
     163    126161232 :             SET_SRC (pat) = mem;
     164    126161232 :             SET_DEST (pat) = reg;
     165    126161232 :             if (recog (pat, insn, &num_clobbers) >= 0)
     166      7401001 :               direct_load[(int) mode] = 1;
     167              : 
     168    126161232 :             SET_SRC (pat) = mem1;
     169    126161232 :             SET_DEST (pat) = reg;
     170    126161232 :             if (recog (pat, insn, &num_clobbers) >= 0)
     171      7401001 :               direct_load[(int) mode] = 1;
     172              : 
     173    126161232 :             SET_SRC (pat) = reg;
     174    126161232 :             SET_DEST (pat) = mem;
     175    126161232 :             if (recog (pat, insn, &num_clobbers) >= 0)
     176      7401001 :               direct_store[(int) mode] = 1;
     177              : 
     178    126161232 :             SET_SRC (pat) = reg;
     179    126161232 :             SET_DEST (pat) = mem1;
     180    126161232 :             if (recog (pat, insn, &num_clobbers) >= 0)
     181      7401001 :               direct_store[(int) mode] = 1;
     182              :           }
     183              :     }
     184              : 
     185       225810 :   mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
     186              : 
     187       220100 :   opt_scalar_float_mode mode_iter;
     188      1540700 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
     189              :     {
     190      1320600 :       scalar_float_mode mode = mode_iter.require ();
     191      1320600 :       scalar_float_mode srcmode;
     192      4622100 :       FOR_EACH_MODE_UNTIL (srcmode, mode)
     193              :         {
     194      3301500 :           enum insn_code ic;
     195              : 
     196      3301500 :           ic = can_extend_p (mode, srcmode, 0);
     197      3301500 :           if (ic == CODE_FOR_nothing)
     198      2636410 :             continue;
     199              : 
     200       665090 :           PUT_MODE (mem, srcmode);
     201              : 
     202       665090 :           if (insn_operand_matches (ic, 1, mem))
     203       662924 :             float_extend_from_mem[mode][srcmode] = true;
     204              :         }
     205              :     }
     206       220100 : }
     207              : 
     208              : /* This is run at the start of compiling a function.  */
     209              : 
     210              : void
     211      1738005 : init_expr (void)
     212              : {
     213      1738005 :   memset (&crtl->expr, 0, sizeof (crtl->expr));
     214      1738005 : }
     215              : 
     216              : /* Copy data from FROM to TO, where the machine modes are not the same.
     217              :    Both modes may be integer, or both may be floating, or both may be
     218              :    fixed-point.
     219              :    UNSIGNEDP should be nonzero if FROM is an unsigned type.
     220              :    This causes zero-extension instead of sign-extension.  */
     221              : 
     222              : void
     223      2183006 : convert_move (rtx to, rtx from, int unsignedp)
     224              : {
     225      2183006 :   machine_mode to_mode = GET_MODE (to);
     226      2183006 :   machine_mode from_mode = GET_MODE (from);
     227              : 
     228      2183006 :   gcc_assert (to_mode != BLKmode);
     229      2183006 :   gcc_assert (from_mode != BLKmode);
     230              : 
     231              :   /* If the source and destination are already the same, then there's
     232              :      nothing to do.  */
     233      2183006 :   if (to == from)
     234      2183006 :     return;
     235              : 
     236              :   /* If FROM is a SUBREG that indicates that we have already done at least
     237              :      the required extension, strip it.  We don't handle such SUBREGs as
     238              :      TO here.  */
     239              : 
     240      2183006 :   scalar_int_mode to_int_mode;
     241      2183006 :   if (GET_CODE (from) == SUBREG
     242       186942 :       && SUBREG_PROMOTED_VAR_P (from)
     243      2183013 :       && is_a <scalar_int_mode> (to_mode, &to_int_mode)
     244      2183013 :       && (GET_MODE_PRECISION (subreg_promoted_mode (from))
     245            7 :           >= GET_MODE_PRECISION (to_int_mode))
     246      2183013 :       && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
     247              :     {
     248            0 :       scalar_int_mode int_orig_mode;
     249            0 :       scalar_int_mode int_inner_mode;
     250            0 :       machine_mode orig_mode = GET_MODE (from);
     251              : 
     252            0 :       from = gen_lowpart (to_int_mode, SUBREG_REG (from));
     253            0 :       from_mode = to_int_mode;
     254              : 
     255              :       /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
     256              :          the original mode, but narrower than the inner mode.  */
     257            0 :       if (GET_CODE (from) == SUBREG
     258            0 :           && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
     259            0 :           && GET_MODE_PRECISION (to_int_mode)
     260            0 :              > GET_MODE_PRECISION (int_orig_mode)
     261            0 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
     262              :                                      &int_inner_mode)
     263            0 :           && GET_MODE_PRECISION (int_inner_mode)
     264            0 :              > GET_MODE_PRECISION (to_int_mode))
     265              :         {
     266            0 :           SUBREG_PROMOTED_VAR_P (from) = 1;
     267            0 :           SUBREG_PROMOTED_SET (from, unsignedp);
     268              :         }
     269              :     }
     270              : 
     271      2183006 :   gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
     272              : 
     273      2183006 :   if (to_mode == from_mode
     274      2125905 :       || (from_mode == VOIDmode && CONSTANT_P (from)))
     275              :     {
     276        57328 :       emit_move_insn (to, from);
     277        57328 :       return;
     278              :     }
     279              : 
     280      2125678 :   if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
     281              :     {
     282        30860 :       if (GET_MODE_UNIT_PRECISION (to_mode)
     283        15430 :           > GET_MODE_UNIT_PRECISION (from_mode))
     284              :         {
     285         5027 :           optab op = unsignedp ? zext_optab : sext_optab;
     286         5027 :           insn_code icode = convert_optab_handler (op, to_mode, from_mode);
     287         5027 :           if (icode != CODE_FOR_nothing)
     288              :             {
     289         1193 :               emit_unop_insn (icode, to, from,
     290              :                               unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
     291         1193 :               return;
     292              :             }
     293              :         }
     294              : 
     295        28474 :       if (GET_MODE_UNIT_PRECISION (to_mode)
     296        14237 :           < GET_MODE_UNIT_PRECISION (from_mode))
     297              :         {
     298         2329 :           insn_code icode = convert_optab_handler (trunc_optab,
     299              :                                                    to_mode, from_mode);
     300         2329 :           if (icode != CODE_FOR_nothing)
     301              :             {
     302         1077 :               emit_unop_insn (icode, to, from, TRUNCATE);
     303         1077 :               return;
     304              :             }
     305              :         }
     306              : 
     307        39480 :       gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
     308              :                             GET_MODE_BITSIZE (to_mode)));
     309              : 
     310        13160 :       if (VECTOR_MODE_P (to_mode))
     311        13160 :         from = force_subreg (to_mode, from, GET_MODE (from), 0);
     312              :       else
     313            0 :         to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
     314              : 
     315        13160 :       emit_move_insn (to, from);
     316        13160 :       return;
     317              :     }
     318              : 
     319      2110248 :   if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
     320              :     {
     321            0 :       convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
     322            0 :       convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
     323            0 :       return;
     324              :     }
     325              : 
     326      2110248 :   convert_mode_scalar (to, from, unsignedp);
     327              : }
     328              : 
     329              : /* Like convert_move, but deals only with scalar modes.  */
     330              : 
     331              : static void
     332      2110310 : convert_mode_scalar (rtx to, rtx from, int unsignedp)
     333              : {
     334              :   /* Both modes should be scalar types.  */
     335      2110315 :   scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
     336      2110315 :   scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
     337      2110315 :   bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
     338      2110315 :   bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
     339      2110315 :   enum insn_code code;
     340      2110315 :   rtx libcall;
     341              : 
     342      2110315 :   gcc_assert (to_real == from_real);
     343              : 
     344              :   /* rtx code for making an equivalent value.  */
     345      3217093 :   enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
     346      2110315 :                               : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
     347              : 
     348      2110315 :   auto acceptable_same_precision_modes
     349          580 :     = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
     350              :     {
     351          580 :       if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
     352              :         return true;
     353              : 
     354              :       /* arm_bfloat_half_format <-> ieee_half_format */
     355            2 :       if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
     356            1 :            && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
     357            2 :           || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     358            1 :               && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
     359              :         return true;
     360              : 
     361              :       /* ibm_extended_format <-> ieee_quad_format */
     362            0 :       if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
     363            0 :            && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
     364            0 :           || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
     365            0 :               && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
     366            0 :         return true;
     367              : 
     368              :       return false;
     369              :     };
     370              : 
     371      2110315 :   if (to_real)
     372              :     {
     373       189559 :       rtx value;
     374       189559 :       rtx_insn *insns;
     375       189559 :       convert_optab tab;
     376              : 
     377       189559 :       gcc_assert ((GET_MODE_PRECISION (from_mode)
     378              :                    != GET_MODE_PRECISION (to_mode))
     379              :                   || acceptable_same_precision_modes (from_mode, to_mode));
     380              : 
     381       189559 :       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
     382              :         {
     383          580 :           if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     384            1 :                && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
     385          580 :               || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
     386            0 :                   && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
     387              :             /* libgcc implements just __trunchfbf2, not __extendhfbf2;
     388              :                and __trunctfkf2, not __extendtfkf2.  */
     389              :             tab = trunc_optab;
     390              :           else
     391              :             /* Conversion between decimal float and binary float, same
     392              :                size.  */
     393          579 :             tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
     394              :         }
     395       188979 :       else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
     396              :         tab = sext_optab;
     397              :       else
     398        18895 :         tab = trunc_optab;
     399              : 
     400              :       /* Try converting directly if the insn is supported.  */
     401              : 
     402       189559 :       code = convert_optab_handler (tab, to_mode, from_mode);
     403       189559 :       if (code != CODE_FOR_nothing)
     404              :         {
     405       161701 :           emit_unop_insn (code, to, from,
     406              :                           tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
     407       161701 :           return;
     408              :         }
     409              : 
     410              : #ifdef HAVE_SFmode
     411        27858 :       if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
     412        27858 :           && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
     413              :         {
     414         3245 :           if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
     415              :             {
     416              :               /* To cut down on libgcc size, implement
     417              :                  BFmode -> {DF,XF,TF}mode conversions by
     418              :                  BFmode -> SFmode -> {DF,XF,TF}mode conversions.  */
     419            4 :               rtx temp = gen_reg_rtx (SFmode);
     420            4 :               convert_mode_scalar (temp, from, unsignedp);
     421            4 :               convert_mode_scalar (to, temp, unsignedp);
     422            4 :               return;
     423              :             }
     424         3241 :           if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
     425              :             {
     426              :               /* Similarly, implement BFmode -> HFmode as
     427              :                  BFmode -> SFmode -> HFmode conversion where SFmode
     428              :                  has superset of BFmode values.  We don't need
     429              :                  to handle sNaNs by raising exception and turning
     430              :                  it into qNaN though, as that can be done in the
     431              :                  SFmode -> HFmode conversion too.  */
     432            1 :               rtx temp = gen_reg_rtx (SFmode);
     433            1 :               int save_flag_finite_math_only = flag_finite_math_only;
     434            1 :               flag_finite_math_only = true;
     435            1 :               convert_mode_scalar (temp, from, unsignedp);
     436            1 :               flag_finite_math_only = save_flag_finite_math_only;
     437            1 :               convert_mode_scalar (to, temp, unsignedp);
     438            1 :               return;
     439              :             }
     440         3240 :           if (to_mode == SFmode
     441         3240 :               && !HONOR_NANS (from_mode)
     442           58 :               && !HONOR_NANS (to_mode)
     443         3298 :               && optimize_insn_for_speed_p ())
     444              :             {
     445              :               /* If we don't expect sNaNs, for BFmode -> SFmode we can just
     446              :                  shift the bits up.  */
     447           57 :               machine_mode fromi_mode, toi_mode;
     448          114 :               if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
     449           57 :                                      0).exists (&fromi_mode)
     450           57 :                   && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
     451            0 :                                         0).exists (&toi_mode))
     452              :                 {
     453           57 :                   start_sequence ();
     454           57 :                   rtx fromi = force_lowpart_subreg (fromi_mode, from,
     455              :                                                     from_mode);
     456           57 :                   rtx tof = NULL_RTX;
     457           57 :                   if (fromi)
     458              :                     {
     459           57 :                       rtx toi;
     460           57 :                       if (GET_MODE (fromi) == VOIDmode)
     461            0 :                         toi = simplify_unary_operation (ZERO_EXTEND, toi_mode,
     462              :                                                         fromi, fromi_mode);
     463              :                       else
     464              :                         {
     465           57 :                           toi = gen_reg_rtx (toi_mode);
     466           57 :                           convert_mode_scalar (toi, fromi, 1);
     467              :                         }
     468           57 :                       toi
     469          114 :                         = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
     470           57 :                                               GET_MODE_PRECISION (to_mode)
     471           57 :                                               - GET_MODE_PRECISION (from_mode),
     472              :                                               NULL_RTX, 1);
     473           57 :                       if (toi)
     474              :                         {
     475           57 :                           tof = force_lowpart_subreg (to_mode, toi, toi_mode);
     476           57 :                           if (tof)
     477           57 :                             emit_move_insn (to, tof);
     478              :                         }
     479              :                     }
     480           57 :                   insns = end_sequence ();
     481           57 :                   if (tof)
     482              :                     {
     483           57 :                       emit_insn (insns);
     484           57 :                       return;
     485              :                     }
     486              :                 }
     487              :             }
     488              :         }
     489        27796 :       if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
     490         4274 :           && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
     491         1572 :           && !HONOR_NANS (from_mode)
     492            0 :           && !HONOR_NANS (to_mode)
     493            0 :           && !flag_rounding_math
     494        27796 :           && optimize_insn_for_speed_p ())
     495              :         {
     496              :           /* If we don't expect qNaNs nor sNaNs and can assume rounding
     497              :              to nearest, we can expand the conversion inline as
     498              :              (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16.  */
     499            0 :           machine_mode fromi_mode, toi_mode;
     500            0 :           if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
     501            0 :                                  0).exists (&fromi_mode)
     502            0 :               && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
     503            0 :                                     0).exists (&toi_mode))
     504              :             {
     505            0 :               start_sequence ();
     506            0 :               rtx fromi = force_lowpart_subreg (fromi_mode, from, from_mode);
     507            0 :               rtx tof = NULL_RTX;
     508            0 :               do
     509              :                 {
     510            0 :                   if (!fromi)
     511              :                     break;
     512            0 :                   int shift = (GET_MODE_PRECISION (from_mode)
     513            0 :                                - GET_MODE_PRECISION (to_mode));
     514            0 :                   rtx temp1
     515            0 :                     = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
     516              :                                           shift, NULL_RTX, 1);
     517            0 :                   if (!temp1)
     518              :                     break;
     519            0 :                   rtx temp2
     520            0 :                     = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
     521              :                                     NULL_RTX, 1, OPTAB_DIRECT);
     522            0 :                   if (!temp2)
     523              :                     break;
     524            0 :                   rtx temp3
     525            0 :                     = expand_binop (fromi_mode, add_optab, fromi,
     526              :                                     gen_int_mode ((HOST_WIDE_INT_1U
     527            0 :                                                    << (shift - 1)) - 1,
     528              :                                                   fromi_mode), NULL_RTX,
     529              :                                     1, OPTAB_DIRECT);
     530            0 :                   if (!temp3)
     531              :                     break;
     532            0 :                   rtx temp4
     533            0 :                     = expand_binop (fromi_mode, add_optab, temp3, temp2,
     534              :                                     NULL_RTX, 1, OPTAB_DIRECT);
     535            0 :                   if (!temp4)
     536              :                     break;
     537            0 :                   rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
     538              :                                                   temp4, shift, NULL_RTX, 1);
     539            0 :                   if (!temp5)
     540              :                     break;
     541            0 :                   rtx temp6 = force_lowpart_subreg (toi_mode, temp5,
     542              :                                                     fromi_mode);
     543            0 :                   if (!temp6)
     544              :                     break;
     545            0 :                   tof = force_lowpart_subreg (to_mode, temp6, toi_mode);
     546            0 :                   if (tof)
     547            0 :                     emit_move_insn (to, tof);
     548              :                 }
     549              :               while (0);
     550            0 :               insns = end_sequence ();
     551            0 :               if (tof)
     552              :                 {
     553            0 :                   emit_insn (insns);
     554            0 :                   return;
     555              :                 }
     556              :             }
     557              :         }
     558              : #endif
     559              : 
     560              :       /* Otherwise use a libcall.  */
     561        27796 :       libcall = convert_optab_libfunc (tab, to_mode, from_mode);
     562              : 
     563              :       /* Is this conversion implemented yet?  */
     564        27796 :       gcc_assert (libcall);
     565              : 
     566        27796 :       start_sequence ();
     567        27796 :       value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
     568              :                                        from, from_mode);
     569        27796 :       insns = end_sequence ();
     570        27796 :       emit_libcall_block (insns, to, value,
     571         6785 :                           tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
     572              :                                                                        from)
     573        21011 :                           : gen_rtx_FLOAT_EXTEND (to_mode, from));
     574        27796 :       return;
     575              :     }
     576              : 
     577              :   /* Handle pointer conversion.  */                     /* SPEE 900220.  */
     578              :   /* If the target has a converter from FROM_MODE to TO_MODE, use it.  */
     579      1920756 :   {
     580      1920756 :     convert_optab ctab;
     581              : 
     582      1920756 :     if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
     583              :       ctab = trunc_optab;
     584      1720265 :     else if (unsignedp)
     585              :       ctab = zext_optab;
     586              :     else
     587       831781 :       ctab = sext_optab;
     588              : 
     589      1920756 :     if (convert_optab_handler (ctab, to_mode, from_mode)
     590              :         != CODE_FOR_nothing)
     591              :       {
     592      1649495 :         emit_unop_insn (convert_optab_handler (ctab, to_mode, from_mode),
     593              :                         to, from, UNKNOWN);
     594      1649495 :         return;
     595              :       }
     596              :   }
     597              : 
     598              :   /* Targets are expected to provide conversion insns between PxImode and
     599              :      xImode for all MODE_PARTIAL_INT modes they use, but no others.  */
     600       271261 :   if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
     601              :     {
     602            0 :       scalar_int_mode full_mode
     603            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (to_mode)).require ();
     604              : 
     605            0 :       gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
     606              :                   != CODE_FOR_nothing);
     607              : 
     608            0 :       if (full_mode != from_mode)
     609            0 :         from = convert_to_mode (full_mode, from, unsignedp);
     610            0 :       emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, full_mode),
     611              :                       to, from, UNKNOWN);
     612            0 :       return;
     613              :     }
     614       271261 :   if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
     615              :     {
     616            0 :       rtx new_from;
     617            0 :       scalar_int_mode full_mode
     618            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (from_mode)).require ();
     619            0 :       convert_optab ctab = unsignedp ? zext_optab : sext_optab;
     620            0 :       enum insn_code icode;
     621              : 
     622            0 :       icode = convert_optab_handler (ctab, full_mode, from_mode);
     623            0 :       gcc_assert (icode != CODE_FOR_nothing);
     624              : 
     625            0 :       if (to_mode == full_mode)
     626              :         {
     627            0 :           emit_unop_insn (icode, to, from, UNKNOWN);
     628            0 :           return;
     629              :         }
     630              : 
     631            0 :       new_from = gen_reg_rtx (full_mode);
     632            0 :       emit_unop_insn (icode, new_from, from, UNKNOWN);
     633              : 
     634              :       /* else proceed to integer conversions below.  */
     635            0 :       from_mode = full_mode;
     636            0 :       from = new_from;
     637              :     }
     638              : 
     639              :    /* Make sure both are fixed-point modes or both are not.  */
     640       271261 :    gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
     641              :                ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
     642       271261 :    if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
     643              :     {
     644              :       /* If we widen from_mode to to_mode and they are in the same class,
     645              :          we won't saturate the result.
     646              :          Otherwise, always saturate the result to play safe.  */
     647            0 :       if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
     648            0 :           && GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
     649            0 :         expand_fixed_convert (to, from, 0, 0);
     650              :       else
     651            0 :         expand_fixed_convert (to, from, 0, 1);
     652              :       return;
     653              :     }
     654              : 
     655              :   /* Now both modes are integers.  */
     656              : 
     657              :   /* Handle expanding beyond a word.  */
     658       271261 :   if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)
     659       273962 :       && GET_MODE_PRECISION (to_mode) > BITS_PER_WORD)
     660              :     {
     661        70770 :       rtx_insn *insns;
     662        70770 :       rtx lowpart;
     663        70770 :       rtx fill_value;
     664        70770 :       rtx lowfrom;
     665        70770 :       int i;
     666        70770 :       scalar_mode lowpart_mode;
     667       141540 :       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
     668              : 
     669              :       /* Try converting directly if the insn is supported.  */
     670        70770 :       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
     671              :           != CODE_FOR_nothing)
     672              :         {
     673              :           /* If FROM is a SUBREG, put it into a register.  Do this
     674              :              so that we always generate the same set of insns for
     675              :              better cse'ing; if an intermediate assignment occurred,
     676              :              we won't be doing the operation directly on the SUBREG.  */
     677            0 :           if (optimize > 0 && GET_CODE (from) == SUBREG)
     678            0 :             from = force_reg (from_mode, from);
     679            0 :           emit_unop_insn (code, to, from, equiv_code);
     680            0 :           return;
     681              :         }
     682              :       /* Next, try converting via full word.  */
     683        70770 :       else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD
     684        70770 :                && ((code = can_extend_p (to_mode, word_mode, unsignedp))
     685              :                    != CODE_FOR_nothing))
     686              :         {
     687        70631 :           rtx word_to = gen_reg_rtx (word_mode);
     688        70631 :           if (REG_P (to))
     689              :             {
     690        70558 :               if (reg_overlap_mentioned_p (to, from))
     691            0 :                 from = force_reg (from_mode, from);
     692        70558 :               emit_clobber (to);
     693              :             }
     694        70631 :           convert_move (word_to, from, unsignedp);
     695        70631 :           emit_unop_insn (code, to, word_to, equiv_code);
     696        70631 :           return;
     697              :         }
     698              : 
     699              :       /* No special multiword conversion insn; do it by hand.  */
     700          139 :       start_sequence ();
     701              : 
     702              :       /* Since we will turn this into a no conflict block, we must ensure
     703              :          the source does not overlap the target so force it into an isolated
     704              :          register when maybe so.  Likewise for any MEM input, since the
     705              :          conversion sequence might require several references to it and we
     706              :          must ensure we're getting the same value every time.  */
     707              : 
     708          139 :       if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
     709            0 :         from = force_reg (from_mode, from);
     710              : 
     711              :       /* Get a copy of FROM widened to a word, if necessary.  */
     712          278 :       if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD)
     713            0 :         lowpart_mode = word_mode;
     714              :       else
     715              :         lowpart_mode = from_mode;
     716              : 
     717          139 :       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
     718              : 
     719          139 :       lowpart = gen_lowpart (lowpart_mode, to);
     720          139 :       emit_move_insn (lowpart, lowfrom);
     721              : 
     722              :       /* Compute the value to put in each remaining word.  */
     723          139 :       if (unsignedp)
     724          117 :         fill_value = const0_rtx;
     725              :       else
     726           22 :         fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
     727              :                                             LT, lowfrom, const0_rtx,
     728              :                                             lowpart_mode, 0, -1);
     729              : 
     730              :       /* Fill the remaining words.  */
     731          695 :       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
     732              :         {
     733          278 :           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
     734          278 :           rtx subword = operand_subword (to, index, 1, to_mode);
     735              : 
     736          278 :           gcc_assert (subword);
     737              : 
     738          278 :           if (fill_value != subword)
     739          278 :             emit_move_insn (subword, fill_value);
     740              :         }
     741              : 
     742          139 :       insns = end_sequence ();
     743              : 
     744          139 :       emit_insn (insns);
     745          139 :       return;
     746              :     }
     747              : 
     748              :   /* Truncating multi-word to a word or less.  */
     749       200491 :   if (GET_MODE_PRECISION (from_mode) > BITS_PER_WORD
     750       200491 :       && GET_MODE_PRECISION (to_mode) <= BITS_PER_WORD)
     751              :     {
     752        79028 :       if (!((MEM_P (from)
     753          575 :              && ! MEM_VOLATILE_P (from)
     754          575 :              && direct_load[(int) to_mode]
     755          575 :              && ! mode_dependent_address_p (XEXP (from, 0),
     756          575 :                                             MEM_ADDR_SPACE (from)))
     757        48466 :             || REG_P (from)
     758              :             || GET_CODE (from) == SUBREG))
     759            0 :         from = force_reg (from_mode, from);
     760        49041 :       convert_move (to, gen_lowpart (word_mode, from), 0);
     761        49041 :       return;
     762              :     }
     763              : 
     764              :   /* Now follow all the conversions between integers
     765              :      no more than a word long.  */
     766              : 
     767              :   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
     768       302900 :   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
     769       151450 :       && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
     770              :     {
     771       163520 :       if (!((MEM_P (from)
     772        12504 :              && ! MEM_VOLATILE_P (from)
     773        12445 :              && direct_load[(int) to_mode]
     774        12445 :              && ! mode_dependent_address_p (XEXP (from, 0),
     775        12445 :                                             MEM_ADDR_SPACE (from)))
     776       139005 :             || REG_P (from)
     777              :             || GET_CODE (from) == SUBREG))
     778          923 :         from = force_reg (from_mode, from);
     779       127858 :       if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
     780       151451 :           && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
     781            0 :         from = copy_to_reg (from);
     782       151450 :       emit_move_insn (to, gen_lowpart (to_mode, from));
     783       151450 :       return;
     784              :     }
     785              : 
     786              :   /* Handle extension.  */
     787            0 :   if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode))
     788              :     {
     789              :       /* Convert directly if that works.  */
     790            0 :       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
     791              :           != CODE_FOR_nothing)
     792              :         {
     793            0 :           emit_unop_insn (code, to, from, equiv_code);
     794            0 :           return;
     795              :         }
     796              :       else
     797              :         {
     798            0 :           rtx tmp;
     799            0 :           int shift_amount;
     800              : 
     801              :           /* Search for a mode to convert via.  */
     802            0 :           opt_scalar_mode intermediate_iter;
     803            0 :           FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
     804              :             {
     805            0 :               scalar_mode intermediate = intermediate_iter.require ();
     806            0 :               if (((can_extend_p (to_mode, intermediate, unsignedp)
     807              :                     != CODE_FOR_nothing)
     808            0 :                    || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
     809            0 :                        && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
     810              :                                                          intermediate)))
     811            0 :                   && (can_extend_p (intermediate, from_mode, unsignedp)
     812              :                       != CODE_FOR_nothing))
     813              :                 {
     814            0 :                   convert_move (to, convert_to_mode (intermediate, from,
     815              :                                                      unsignedp), unsignedp);
     816            0 :                   return;
     817              :                 }
     818              :             }
     819              : 
     820              :           /* No suitable intermediate mode.
     821              :              Generate what we need with shifts.  */
     822            0 :           shift_amount = (GET_MODE_PRECISION (to_mode)
     823            0 :                           - GET_MODE_PRECISION (from_mode));
     824            0 :           from = gen_lowpart (to_mode, force_reg (from_mode, from));
     825            0 :           tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
     826              :                               to, unsignedp);
     827            0 :           tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
     828              :                               to, unsignedp);
     829            0 :           if (tmp != to)
     830            0 :             emit_move_insn (to, tmp);
     831              :           return;
     832              :         }
     833              :     }
     834              : 
     835              :   /* Support special truncate insns for certain modes.  */
     836            0 :   if (convert_optab_handler (trunc_optab, to_mode,
     837              :                              from_mode) != CODE_FOR_nothing)
     838              :     {
     839            0 :       emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, from_mode),
     840              :                       to, from, UNKNOWN);
     841            0 :       return;
     842              :     }
     843              : 
     844              :   /* Handle truncation of volatile memrefs, and so on;
     845              :      the things that couldn't be truncated directly,
     846              :      and for which there was no special instruction.
     847              : 
     848              :      ??? Code above formerly short-circuited this, for most integer
     849              :      mode pairs, with a force_reg in from_mode followed by a recursive
     850              :      call to this routine.  Appears always to have been wrong.  */
     851            0 :   if (GET_MODE_PRECISION (to_mode) < GET_MODE_PRECISION (from_mode))
     852              :     {
     853            0 :       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
     854            0 :       emit_move_insn (to, temp);
     855            0 :       return;
     856              :     }
     857              : 
     858              :   /* Mode combination is not recognized.  */
     859            0 :   gcc_unreachable ();
     860              : }
     861              : 
     862              : /* Return an rtx for a value that would result
     863              :    from converting X to mode MODE.
     864              :    Both X and MODE may be floating, or both integer.
     865              :    UNSIGNEDP is nonzero if X is an unsigned value.
     866              :    This can be done by referring to a part of X in place
     867              :    or by copying to a new temporary with conversion.  */
     868              : 
     869              : rtx
     870      2372162 : convert_to_mode (machine_mode mode, rtx x, int unsignedp)
     871              : {
     872      2372162 :   return convert_modes (mode, VOIDmode, x, unsignedp);
     873              : }
     874              : 
     875              : /* Return an rtx for a value that would result
     876              :    from converting X from mode OLDMODE to mode MODE.
     877              :    Both modes may be floating, or both integer.
     878              :    UNSIGNEDP is nonzero if X is an unsigned value.
     879              : 
     880              :    This can be done by referring to a part of X in place
     881              :    or by copying to a new temporary with conversion.
     882              : 
     883              :    You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.  */
     884              : 
     885              : rtx
     886      5208668 : convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
     887              : {
     888      5208668 :   rtx temp;
     889      5208668 :   scalar_int_mode int_mode;
     890              : 
     891              :   /* If FROM is a SUBREG that indicates that we have already done at least
     892              :      the required extension, strip it.  */
     893              : 
     894      5208668 :   if (GET_CODE (x) == SUBREG
     895       139720 :       && SUBREG_PROMOTED_VAR_P (x)
     896      5208675 :       && is_a <scalar_int_mode> (mode, &int_mode)
     897      5208675 :       && (GET_MODE_PRECISION (subreg_promoted_mode (x))
     898           14 :           >= GET_MODE_PRECISION (int_mode))
     899      5208682 :       && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
     900              :     {
     901            7 :       scalar_int_mode int_orig_mode;
     902            7 :       scalar_int_mode int_inner_mode;
     903            7 :       machine_mode orig_mode = GET_MODE (x);
     904            7 :       x = gen_lowpart (int_mode, SUBREG_REG (x));
     905              : 
     906              :       /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
     907              :          the original mode, but narrower than the inner mode.  */
     908            7 :       if (GET_CODE (x) == SUBREG
     909            0 :           && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
     910            0 :           && GET_MODE_PRECISION (int_mode)
     911            0 :              > GET_MODE_PRECISION (int_orig_mode)
     912            0 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
     913              :                                      &int_inner_mode)
     914            7 :           && GET_MODE_PRECISION (int_inner_mode)
     915            0 :              > GET_MODE_PRECISION (int_mode))
     916              :         {
     917            0 :           SUBREG_PROMOTED_VAR_P (x) = 1;
     918            0 :           SUBREG_PROMOTED_SET (x, unsignedp);
     919              :         }
     920              :     }
     921              : 
     922      5208668 :   if (GET_MODE (x) != VOIDmode)
     923      2862359 :     oldmode = GET_MODE (x);
     924              : 
     925      5208668 :   if (mode == oldmode)
     926              :     return x;
     927              : 
     928      3779353 :   if (CONST_SCALAR_INT_P (x)
     929      3779353 :       && is_a <scalar_int_mode> (mode, &int_mode))
     930              :     {
     931              :       /* If the caller did not tell us the old mode, then there is not
     932              :          much to do with respect to canonicalization.  We have to
     933              :          assume that all the bits are significant.  */
     934      2025081 :       if (!is_a <scalar_int_mode> (oldmode))
     935      1694868 :         oldmode = MAX_MODE_INT;
     936      2025081 :       wide_int w = wide_int::from (rtx_mode_t (x, oldmode),
     937      2025081 :                                    GET_MODE_PRECISION (int_mode),
     938      2670171 :                                    unsignedp ? UNSIGNED : SIGNED);
     939      2025081 :       return immed_wide_int_const (w, int_mode);
     940      2025081 :     }
     941              : 
     942              :   /* We can do this with a gen_lowpart if both desired and current modes
     943              :      are integer, and this is either a constant integer, a register, or a
     944              :      non-volatile MEM. */
     945      1754272 :   scalar_int_mode int_oldmode;
     946      1754272 :   if (is_int_mode (mode, &int_mode)
     947      1659573 :       && is_int_mode (oldmode, &int_oldmode)
     948      1659573 :       && GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (int_oldmode)
     949       456013 :       && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
     950        12875 :           || CONST_POLY_INT_P (x)
     951       443138 :           || (REG_P (x)
     952       406930 :               && (!HARD_REGISTER_P (x)
     953         1069 :                   || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
     954       419805 :               && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
     955       419805 :    return gen_lowpart (int_mode, x);
     956              : 
     957              :   /* Converting from integer constant into mode is always equivalent to an
     958              :      subreg operation.  */
     959      1334467 :   if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
     960              :     {
     961            0 :       gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
     962              :                             GET_MODE_BITSIZE (oldmode)));
     963            0 :       return force_subreg (mode, x, oldmode, 0);
     964              :     }
     965              : 
     966      1334467 :   temp = gen_reg_rtx (mode);
     967      1334467 :   convert_move (temp, x, unsignedp);
     968      1334467 :   return temp;
     969              : }
     970              : 
     971              : /* Variant of convert_modes for ABI parameter passing/return.
     972              :    Return an rtx for a value that would result from converting X from
     973              :    a floating point mode FMODE to wider integer mode MODE.  */
     974              : 
     975              : rtx
     976            0 : convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
     977              : {
     978            0 :   gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
     979            0 :   scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
     980            0 :   rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
     981            0 :   return convert_modes (mode, tmp_mode, tmp, 1);
     982              : }
     983              : 
     984              : /* Variant of convert_modes for ABI parameter passing/return.
     985              :    Return an rtx for a value that would result from converting X from
     986              :    an integer mode IMODE to a narrower floating point mode MODE.  */
     987              : 
     988              : rtx
     989            0 : convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
     990              : {
     991            0 :   gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
     992            0 :   scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
     993            0 :   rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
     994            0 :   return gen_lowpart_SUBREG (mode, tmp);
     995              : }
     996              : 
     997              : /* Return the largest alignment we can use for doing a move (or store)
     998              :    of MAX_PIECES.  ALIGN is the largest alignment we could use.  */
     999              : 
    1000              : static unsigned int
    1001      2778067 : alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
    1002              : {
    1003      2778067 :   scalar_int_mode tmode
    1004      2778067 :     = int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
    1005              : 
    1006      2778067 :   if (align >= GET_MODE_ALIGNMENT (tmode))
    1007      2192271 :     align = GET_MODE_ALIGNMENT (tmode);
    1008              :   else
    1009              :     {
    1010       585796 :       scalar_int_mode xmode = NARROWEST_INT_MODE;
    1011       585796 :       opt_scalar_int_mode mode_iter;
    1012      3531215 :       FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    1013              :         {
    1014      3525487 :           tmode = mode_iter.require ();
    1015      3525487 :           if (GET_MODE_SIZE (tmode) > max_pieces
    1016      3525487 :               || targetm.slow_unaligned_access (tmode, align))
    1017              :             break;
    1018      2945419 :           xmode = tmode;
    1019              :         }
    1020              : 
    1021       585796 :       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
    1022              :     }
    1023              : 
    1024      2778067 :   return align;
    1025              : }
    1026              : 
    1027              : /* Return true if we know how to implement OP using vectors of bytes.  */
    1028              : static bool
    1029      5874768 : can_use_qi_vectors (by_pieces_operation op)
    1030              : {
    1031      5874768 :   return (op == COMPARE_BY_PIECES
    1032            0 :           || op == SET_BY_PIECES
    1033            0 :           || op == CLEAR_BY_PIECES);
    1034              : }
    1035              : 
    1036              : /* Return true if optabs exists for the mode and certain by pieces
    1037              :    operations.  */
    1038              : static bool
    1039     26023442 : by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
    1040              : {
    1041     26023442 :   if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
    1042              :     return false;
    1043              : 
    1044     24660524 :   if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
    1045       688927 :       && VECTOR_MODE_P (mode)
    1046     25154768 :       && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
    1047              :     return false;
    1048              : 
    1049     24611844 :   if (op == COMPARE_BY_PIECES
    1050     24611844 :       && !can_compare_p (EQ, mode, ccp_jump))
    1051              :     return false;
    1052              : 
    1053              :   return true;
    1054              : }
    1055              : 
    1056              : /* Return the widest mode that can be used to perform part of an
    1057              :    operation OP on SIZE bytes.  Try to use QI vector modes where
    1058              :    possible.  */
    1059              : static fixed_size_mode
    1060      5380821 : widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
    1061              : {
    1062      5380821 :   fixed_size_mode result = NARROWEST_INT_MODE;
    1063              : 
    1064      5380821 :   gcc_checking_assert (size > 1);
    1065              : 
    1066              :   /* Use QI vector only if size is wider than a WORD.  */
    1067      5380821 :   if (can_use_qi_vectors (op))
    1068              :     {
    1069       730226 :       machine_mode mode;
    1070       730226 :       fixed_size_mode candidate;
    1071     12056885 :       FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
    1072     12056885 :         if (is_a<fixed_size_mode> (mode, &candidate)
    1073     13163317 :             && GET_MODE_SIZE (candidate) > UNITS_PER_WORD
    1074     12979186 :             && GET_MODE_INNER (candidate) == QImode)
    1075              :           {
    1076      5678892 :             if (GET_MODE_SIZE (candidate) >= size)
    1077              :               break;
    1078      2109220 :             if (by_pieces_mode_supported_p (candidate, op))
    1079     11326659 :               result = candidate;
    1080              :           }
    1081              : 
    1082       730226 :       if (result != NARROWEST_INT_MODE)
    1083       472768 :         return result;
    1084              :     }
    1085              : 
    1086      4908053 :   opt_scalar_int_mode tmode;
    1087      4908053 :   scalar_int_mode mode;
    1088     39264424 :   FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
    1089              :     {
    1090     34356371 :       mode = tmode.require ();
    1091     34356371 :       if (GET_MODE_SIZE (mode) < size
    1092     34356371 :           && by_pieces_mode_supported_p (mode, op))
    1093     23872533 :       result = mode;
    1094              :     }
    1095              : 
    1096      4908053 :   return result;
    1097              : }
    1098              : 
    1099              : /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
    1100              :    and should be performed piecewise.  */
    1101              : 
    1102              : static bool
    1103       969294 : can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
    1104              :                   enum by_pieces_operation op)
    1105              : {
    1106       969294 :   return targetm.use_by_pieces_infrastructure_p (len, align, op,
    1107       969294 :                                                  optimize_insn_for_speed_p ());
    1108              : }
    1109              : 
    1110              : /* Determine whether the LEN bytes can be moved by using several move
    1111              :    instructions.  Return nonzero if a call to move_by_pieces should
    1112              :    succeed.  */
    1113              : 
    1114              : bool
    1115       899640 : can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
    1116              : {
    1117       899640 :   return can_do_by_pieces (len, align, MOVE_BY_PIECES);
    1118              : }
    1119              : 
    1120              : /* Return number of insns required to perform operation OP by pieces
    1121              :    for L bytes.  ALIGN (in bits) is maximum alignment we can assume.  */
    1122              : 
    1123              : unsigned HOST_WIDE_INT
    1124      1964337 : by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
    1125              :                   unsigned int max_size, by_pieces_operation op)
    1126              : {
    1127      1964337 :   unsigned HOST_WIDE_INT n_insns = 0;
    1128      1964337 :   fixed_size_mode mode;
    1129              : 
    1130      1964337 :   if (targetm.overlap_op_by_pieces_p ())
    1131              :     {
    1132              :       /* NB: Round up L and ALIGN to the widest integer mode for
    1133              :          MAX_SIZE.  */
    1134      1964337 :       mode = widest_fixed_size_mode_for_size (max_size, op);
    1135      1964337 :       gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
    1136      3928674 :       unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
    1137      1964337 :       if (up > l)
    1138              :         l = up;
    1139      1964337 :       align = GET_MODE_ALIGNMENT (mode);
    1140              :     }
    1141              : 
    1142      1964337 :   align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
    1143              : 
    1144      5901360 :   while (max_size > 1 && l > 0)
    1145              :     {
    1146      1972686 :       mode = widest_fixed_size_mode_for_size (max_size, op);
    1147      1972686 :       gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
    1148              : 
    1149      1972686 :       unsigned int modesize = GET_MODE_SIZE (mode);
    1150              : 
    1151      1972686 :       if (align >= GET_MODE_ALIGNMENT (mode))
    1152              :         {
    1153      1972686 :           unsigned HOST_WIDE_INT n_pieces = l / modesize;
    1154      1972686 :           l %= modesize;
    1155      1972686 :           switch (op)
    1156              :             {
    1157      1903032 :             default:
    1158      1903032 :               n_insns += n_pieces;
    1159      1903032 :               break;
    1160              : 
    1161        69654 :             case COMPARE_BY_PIECES:
    1162        69654 :               int batch = targetm.compare_by_pieces_branch_ratio (mode);
    1163        69654 :               int batch_ops = 4 * batch - 1;
    1164        69654 :               unsigned HOST_WIDE_INT full = n_pieces / batch;
    1165        69654 :               n_insns += full * batch_ops;
    1166        69654 :               if (n_pieces % batch != 0)
    1167            0 :                 n_insns++;
    1168              :               break;
    1169              : 
    1170              :             }
    1171              :         }
    1172      1972686 :       max_size = modesize;
    1173              :     }
    1174              : 
    1175      1964337 :   gcc_assert (!l);
    1176      1964337 :   return n_insns;
    1177              : }
    1178              : 
    1179              : /* Used when performing piecewise block operations, holds information
    1180              :    about one of the memory objects involved.  The member functions
    1181              :    can be used to generate code for loading from the object and
    1182              :    updating the address when iterating.  */
    1183              : 
    1184              : class pieces_addr
    1185              : {
    1186              :   /* The object being referenced, a MEM.  Can be NULL_RTX to indicate
    1187              :      stack pushes.  */
    1188              :   rtx m_obj;
    1189              :   /* The address of the object.  Can differ from that seen in the
    1190              :      MEM rtx if we copied the address to a register.  */
    1191              :   rtx m_addr;
    1192              :   /* Nonzero if the address on the object has an autoincrement already,
    1193              :      signifies whether that was an increment or decrement.  */
    1194              :   signed char m_addr_inc;
    1195              :   /* Nonzero if we intend to use autoinc without the address already
    1196              :      having autoinc form.  We will insert add insns around each memory
    1197              :      reference, expecting later passes to form autoinc addressing modes.
    1198              :      The only supported options are predecrement and postincrement.  */
    1199              :   signed char m_explicit_inc;
    1200              :   /* True if we have either of the two possible cases of using
    1201              :      autoincrement.  */
    1202              :   bool m_auto;
    1203              :   /* True if this is an address to be used for load operations rather
    1204              :      than stores.  */
    1205              :   bool m_is_load;
    1206              : 
    1207              :   /* Optionally, a function to obtain constants for any given offset into
    1208              :      the objects, and data associated with it.  */
    1209              :   by_pieces_constfn m_constfn;
    1210              :   void *m_cfndata;
    1211              : public:
    1212              :   pieces_addr (rtx, bool, by_pieces_constfn, void *);
    1213              :   rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
    1214              :   void increment_address (HOST_WIDE_INT);
    1215              :   void maybe_predec (HOST_WIDE_INT);
    1216              :   void maybe_postinc (HOST_WIDE_INT);
    1217              :   void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
    1218       759681 :   int get_addr_inc ()
    1219              :   {
    1220       759681 :     return m_addr_inc;
    1221              :   }
    1222              : };
    1223              : 
    1224              : /* Initialize a pieces_addr structure from an object OBJ.  IS_LOAD is
    1225              :    true if the operation to be performed on this object is a load
    1226              :    rather than a store.  For stores, OBJ can be NULL, in which case we
    1227              :    assume the operation is a stack push.  For loads, the optional
    1228              :    CONSTFN and its associated CFNDATA can be used in place of the
    1229              :    memory load.  */
    1230              : 
    1231      1519362 : pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
    1232              :                           void *cfndata)
    1233      1519362 :   : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
    1234              : {
    1235      1519362 :   m_addr_inc = 0;
    1236      1519362 :   m_auto = false;
    1237      1519362 :   if (obj)
    1238              :     {
    1239      1394011 :       rtx addr = XEXP (obj, 0);
    1240      1394011 :       rtx_code code = GET_CODE (addr);
    1241      1394011 :       m_addr = addr;
    1242      1394011 :       bool dec = code == PRE_DEC || code == POST_DEC;
    1243      1394011 :       bool inc = code == PRE_INC || code == POST_INC;
    1244      1394011 :       m_auto = inc || dec;
    1245      1394011 :       if (m_auto)
    1246            0 :         m_addr_inc = dec ? -1 : 1;
    1247              : 
    1248              :       /* While we have always looked for these codes here, the code
    1249              :          implementing the memory operation has never handled them.
    1250              :          Support could be added later if necessary or beneficial.  */
    1251      1394011 :       gcc_assert (code != PRE_INC && code != POST_DEC);
    1252              :     }
    1253              :   else
    1254              :     {
    1255       125351 :       m_addr = NULL_RTX;
    1256       125351 :       if (!is_load)
    1257              :         {
    1258           45 :           m_auto = true;
    1259           45 :           if (STACK_GROWS_DOWNWARD)
    1260           45 :             m_addr_inc = -1;
    1261              :           else
    1262              :             m_addr_inc = 1;
    1263              :         }
    1264              :       else
    1265       125306 :         gcc_assert (constfn != NULL);
    1266              :     }
    1267      1519362 :   m_explicit_inc = 0;
    1268      1519362 :   if (constfn)
    1269       151548 :     gcc_assert (is_load);
    1270      1519362 : }
    1271              : 
    1272              : /* Decide whether to use autoinc for an address involved in a memory op.
    1273              :    MODE is the mode of the accesses, REVERSE is true if we've decided to
    1274              :    perform the operation starting from the end, and LEN is the length of
    1275              :    the operation.  Don't override an earlier decision to set m_auto.  */
    1276              : 
    1277              : void
    1278       377076 : pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
    1279              :                              HOST_WIDE_INT len)
    1280              : {
    1281       377076 :   if (m_auto || m_obj == NULL_RTX)
    1282              :     return;
    1283              : 
    1284       345612 :   bool use_predec = (m_is_load
    1285              :                      ? USE_LOAD_PRE_DECREMENT (mode)
    1286              :                      : USE_STORE_PRE_DECREMENT (mode));
    1287       345612 :   bool use_postinc = (m_is_load
    1288              :                       ? USE_LOAD_POST_INCREMENT (mode)
    1289              :                       : USE_STORE_POST_INCREMENT (mode));
    1290       345612 :   machine_mode addr_mode = get_address_mode (m_obj);
    1291              : 
    1292       345612 :   if (use_predec && reverse)
    1293              :     {
    1294              :       m_addr = copy_to_mode_reg (addr_mode,
    1295              :                                  plus_constant (addr_mode,
    1296              :                                                 m_addr, len));
    1297              :       m_auto = true;
    1298              :       m_explicit_inc = -1;
    1299              :     }
    1300       345612 :   else if (use_postinc && !reverse)
    1301              :     {
    1302              :       m_addr = copy_to_mode_reg (addr_mode, m_addr);
    1303              :       m_auto = true;
    1304              :       m_explicit_inc = 1;
    1305              :     }
    1306       345612 :   else if (CONSTANT_P (m_addr))
    1307        71960 :     m_addr = copy_to_mode_reg (addr_mode, m_addr);
    1308              : }
    1309              : 
    1310              : /* Adjust the address to refer to the data at OFFSET in MODE.  If we
    1311              :    are using autoincrement for this address, we don't add the offset,
    1312              :    but we still modify the MEM's properties.  */
    1313              : 
    1314              : rtx
    1315      4144221 : pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
    1316              :                      by_pieces_prev *prev)
    1317              : {
    1318      4144221 :   if (m_constfn)
    1319              :     /* Pass the previous data to m_constfn.  */
    1320       371492 :     return m_constfn (m_cfndata, prev, offset, mode);
    1321      3772729 :   if (m_obj == NULL_RTX)
    1322              :     return NULL_RTX;
    1323      3772682 :   if (m_auto)
    1324            0 :     return adjust_automodify_address (m_obj, mode, m_addr, offset);
    1325              :   else
    1326      3772682 :     return adjust_address (m_obj, mode, offset);
    1327              : }
    1328              : 
    1329              : /* Emit an add instruction to increment the address by SIZE.  */
    1330              : 
    1331              : void
    1332            0 : pieces_addr::increment_address (HOST_WIDE_INT size)
    1333              : {
    1334            0 :   rtx amount = gen_int_mode (size, GET_MODE (m_addr));
    1335            0 :   emit_insn (gen_add2_insn (m_addr, amount));
    1336            0 : }
    1337              : 
    1338              : /* If we are supposed to decrement the address after each access, emit code
    1339              :    to do so now.  Increment by SIZE (which has should have the correct sign
    1340              :    already).  */
    1341              : 
    1342              : void
    1343      4143574 : pieces_addr::maybe_predec (HOST_WIDE_INT size)
    1344              : {
    1345      4143574 :   if (m_explicit_inc >= 0)
    1346      4143574 :     return;
    1347            0 :   gcc_assert (HAVE_PRE_DECREMENT);
    1348              :   increment_address (size);
    1349              : }
    1350              : 
    1351              : /* If we are supposed to decrement the address after each access, emit code
    1352              :    to do so now.  Increment by SIZE.  */
    1353              : 
    1354              : void
    1355      4143597 : pieces_addr::maybe_postinc (HOST_WIDE_INT size)
    1356              : {
    1357      4143597 :   if (m_explicit_inc <= 0)
    1358      4143597 :     return;
    1359            0 :   gcc_assert (HAVE_POST_INCREMENT);
    1360              :   increment_address (size);
    1361              : }
    1362              : 
    1363              : /* This structure is used by do_op_by_pieces to describe the operation
    1364              :    to be performed.  */
    1365              : 
    1366              : class op_by_pieces_d
    1367              : {
    1368              :  private:
    1369              :   fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
    1370              :   fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
    1371              : 
    1372              :  protected:
    1373              :   pieces_addr m_to, m_from;
    1374              :   /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
    1375              :      use it to check the valid mode size.  */
    1376              :   const unsigned HOST_WIDE_INT m_len;
    1377              :   HOST_WIDE_INT m_offset;
    1378              :   unsigned int m_align;
    1379              :   unsigned int m_max_size;
    1380              :   bool m_reverse;
    1381              :   /* True if this is a stack push.  */
    1382              :   bool m_push;
    1383              :   /* True if targetm.overlap_op_by_pieces_p () returns true.  */
    1384              :   bool m_overlap_op_by_pieces;
    1385              :   /* The type of operation that we're performing.  */
    1386              :   by_pieces_operation m_op;
    1387              : 
    1388              :   /* Virtual functions, overridden by derived classes for the specific
    1389              :      operation.  */
    1390              :   virtual void generate (rtx, rtx, machine_mode) = 0;
    1391              :   virtual bool prepare_mode (machine_mode, unsigned int) = 0;
    1392      1152368 :   virtual void finish_mode (machine_mode)
    1393              :   {
    1394      1152368 :   }
    1395              : 
    1396              :  public:
    1397              :   op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
    1398              :                   void *, unsigned HOST_WIDE_INT, unsigned int, bool,
    1399              :                   by_pieces_operation);
    1400              :   void run ();
    1401              : };
    1402              : 
    1403              : /* The constructor for an op_by_pieces_d structure.  We require two
    1404              :    objects named TO and FROM, which are identified as loads or stores
    1405              :    by TO_LOAD and FROM_LOAD.  If FROM is a load, the optional FROM_CFN
    1406              :    and its associated FROM_CFN_DATA can be used to replace loads with
    1407              :    constant values.  MAX_PIECES describes the maximum number of bytes
    1408              :    at a time which can be moved efficiently.  LEN describes the length
    1409              :    of the operation.  */
    1410              : 
    1411       759681 : op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
    1412              :                                 bool to_load, rtx from, bool from_load,
    1413              :                                 by_pieces_constfn from_cfn,
    1414              :                                 void *from_cfn_data,
    1415              :                                 unsigned HOST_WIDE_INT len,
    1416              :                                 unsigned int align, bool push,
    1417              :                                 by_pieces_operation op)
    1418       759681 :   : m_to (to, to_load, NULL, NULL),
    1419       759681 :     m_from (from, from_load, from_cfn, from_cfn_data),
    1420       759681 :     m_len (len), m_max_size (max_pieces + 1),
    1421       759681 :     m_push (push), m_op (op)
    1422              : {
    1423       759681 :   int toi = m_to.get_addr_inc ();
    1424       759681 :   int fromi = m_from.get_addr_inc ();
    1425       759681 :   if (toi >= 0 && fromi >= 0)
    1426       759636 :     m_reverse = false;
    1427           45 :   else if (toi <= 0 && fromi <= 0)
    1428           45 :     m_reverse = true;
    1429              :   else
    1430            0 :     gcc_unreachable ();
    1431              : 
    1432       759681 :   m_offset = m_reverse ? len : 0;
    1433      2788077 :   align = MIN (to ? MEM_ALIGN (to) : align,
    1434              :                from ? MEM_ALIGN (from) : align);
    1435              : 
    1436              :   /* If copying requires more than two move insns,
    1437              :      copy addresses to registers (to make displacements shorter)
    1438              :      and use post-increment if available.  */
    1439       759681 :   if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
    1440              :     {
    1441              :       /* Find the mode of the largest comparison.  */
    1442       188538 :       fixed_size_mode mode
    1443       188538 :         = widest_fixed_size_mode_for_size (m_max_size, m_op);
    1444              : 
    1445       188538 :       m_from.decide_autoinc (mode, m_reverse, len);
    1446       188538 :       m_to.decide_autoinc (mode, m_reverse, len);
    1447              :     }
    1448              : 
    1449       759691 :   align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
    1450       759681 :   m_align = align;
    1451              : 
    1452       759681 :   m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
    1453       759681 : }
    1454              : 
    1455              : /* This function returns the largest usable integer mode for LEN bytes
    1456              :    whose size is no bigger than size of MODE.  */
    1457              : 
    1458              : fixed_size_mode
    1459      1247158 : op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
    1460              : {
    1461      1547357 :   unsigned int size;
    1462      1847556 :   do
    1463              :     {
    1464      1547357 :       size = GET_MODE_SIZE (mode);
    1465      1547357 :       if (len >= size && prepare_mode (mode, m_align))
    1466              :         break;
    1467              :       /* widest_fixed_size_mode_for_size checks SIZE > 1.  */
    1468       300199 :       mode = widest_fixed_size_mode_for_size (size, m_op);
    1469              :     }
    1470              :   while (1);
    1471      1247158 :   return mode;
    1472              : }
    1473              : 
    1474              : /* Return the smallest integer or QI vector mode that is not narrower
    1475              :    than SIZE bytes.  */
    1476              : 
    1477              : fixed_size_mode
    1478       493947 : op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
    1479              : {
    1480              :   /* Use QI vector only for > size of WORD.  */
    1481       506150 :   if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
    1482              :     {
    1483         8222 :       machine_mode mode;
    1484         8222 :       fixed_size_mode candidate;
    1485       111281 :       FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
    1486       111281 :         if (is_a<fixed_size_mode> (mode, &candidate)
    1487       222562 :             && GET_MODE_INNER (candidate) == QImode)
    1488              :           {
    1489              :             /* Don't return a mode wider than M_LEN.  */
    1490       103458 :             if (GET_MODE_SIZE (candidate) > m_len)
    1491              :               break;
    1492              : 
    1493        49793 :             if (GET_MODE_SIZE (candidate) >= size
    1494        49793 :                 && by_pieces_mode_supported_p (candidate, m_op))
    1495         6286 :               return candidate;
    1496              :           }
    1497              :     }
    1498              : 
    1499       487661 :   return smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
    1500              : }
    1501              : 
    1502              : /* This function contains the main loop used for expanding a block
    1503              :    operation.  First move what we can in the largest integer mode,
    1504              :    then go to successively smaller modes.  For every access, call
    1505              :    GENFUN with the two operands and the EXTRA_DATA.  */
    1506              : 
    1507              : void
    1508       759681 : op_by_pieces_d::run ()
    1509              : {
    1510       759681 :   if (m_len == 0)
    1511              :     return;
    1512              : 
    1513       753211 :   unsigned HOST_WIDE_INT length = m_len;
    1514              : 
    1515              :   /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1.  */
    1516       753211 :   fixed_size_mode mode
    1517       753211 :     = widest_fixed_size_mode_for_size (m_max_size, m_op);
    1518       753211 :   mode = get_usable_mode (mode, length);
    1519              : 
    1520       753211 :   by_pieces_prev to_prev = { nullptr, mode };
    1521       753211 :   by_pieces_prev from_prev = { nullptr, mode };
    1522              : 
    1523      1247158 :   do
    1524              :     {
    1525      1247158 :       unsigned int size = GET_MODE_SIZE (mode);
    1526      1247158 :       rtx to1 = NULL_RTX, from1;
    1527              : 
    1528      3318945 :       while (length >= size)
    1529              :         {
    1530      2071787 :           if (m_reverse)
    1531           47 :             m_offset -= size;
    1532              : 
    1533      2071787 :           to1 = m_to.adjust (mode, m_offset, &to_prev);
    1534      2071787 :           to_prev.data = to1;
    1535      2071787 :           to_prev.mode = mode;
    1536      2071787 :           from1 = m_from.adjust (mode, m_offset, &from_prev);
    1537      2071787 :           from_prev.data = from1;
    1538      2071787 :           from_prev.mode = mode;
    1539              : 
    1540      2071787 :           m_to.maybe_predec (-(HOST_WIDE_INT)size);
    1541      2071787 :           m_from.maybe_predec (-(HOST_WIDE_INT)size);
    1542              : 
    1543      2071787 :           generate (to1, from1, mode);
    1544              : 
    1545      2071787 :           m_to.maybe_postinc (size);
    1546      2071787 :           m_from.maybe_postinc (size);
    1547              : 
    1548      2071787 :           if (!m_reverse)
    1549      2071740 :             m_offset += size;
    1550              : 
    1551      2071787 :           length -= size;
    1552              :         }
    1553              : 
    1554      1247158 :       finish_mode (mode);
    1555              : 
    1556      1247158 :       if (length == 0)
    1557              :         return;
    1558              : 
    1559       493947 :       if (!m_push && m_overlap_op_by_pieces)
    1560              :         {
    1561              :           /* NB: Generate overlapping operations if it is not a stack
    1562              :              push since stack push must not overlap.  Get the smallest
    1563              :              fixed size mode for M_LEN bytes.  */
    1564       493947 :           mode = smallest_fixed_size_mode_for_size (length);
    1565       987894 :           mode = get_usable_mode (mode, GET_MODE_SIZE (mode));
    1566       493947 :           int gap = GET_MODE_SIZE (mode) - length;
    1567       493947 :           if (gap > 0)
    1568              :             {
    1569              :               /* If size of MODE > M_LEN, generate the last operation
    1570              :                  in MODE for the remaining bytes with overlapping memory
    1571              :                  from the previois operation.  */
    1572        48973 :               if (m_reverse)
    1573            0 :                 m_offset += gap;
    1574              :               else
    1575        48973 :                 m_offset -= gap;
    1576        48973 :               length += gap;
    1577              :             }
    1578              :         }
    1579              :       else
    1580              :         {
    1581              :           /* widest_fixed_size_mode_for_size checks SIZE > 1.  */
    1582            0 :           mode = widest_fixed_size_mode_for_size (size, m_op);
    1583            0 :           mode = get_usable_mode (mode, length);
    1584              :         }
    1585              :     }
    1586              :   while (1);
    1587              : }
    1588              : 
    1589              : /* Derived class from op_by_pieces_d, providing support for block move
    1590              :    operations.  */
    1591              : 
    1592              : #ifdef PUSH_ROUNDING
    1593              : #define PUSHG_P(to)  ((to) == nullptr)
    1594              : #else
    1595              : #define PUSHG_P(to)  false
    1596              : #endif
    1597              : 
    1598              : class move_by_pieces_d : public op_by_pieces_d
    1599              : {
    1600              :   insn_gen_fn m_gen_fun;
    1601              :   void generate (rtx, rtx, machine_mode) final override;
    1602              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1603              : 
    1604              :  public:
    1605       571527 :   move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
    1606              :                     unsigned int align)
    1607       571527 :     : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
    1608      1143054 :                       NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
    1609              :   {
    1610       571527 :   }
    1611              :   rtx finish_retmode (memop_ret);
    1612              : };
    1613              : 
    1614              : /* Return true if MODE can be used for a set of copies, given an
    1615              :    alignment ALIGN.  Prepare whatever data is necessary for later
    1616              :    calls to generate.  */
    1617              : 
    1618              : bool
    1619       952537 : move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1620              : {
    1621       952537 :   insn_code icode = optab_handler (mov_optab, mode);
    1622       952537 :   m_gen_fun = GEN_FCN (icode);
    1623       952537 :   return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
    1624              : }
    1625              : 
    1626              : /* A callback used when iterating for a compare_by_pieces_operation.
    1627              :    OP0 and OP1 are the values that have been loaded and should be
    1628              :    compared in MODE.  If OP0 is NULL, this means we should generate a
    1629              :    push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
    1630              :    gen function that should be used to generate the mode.  */
    1631              : 
    1632              : void
    1633      1654776 : move_by_pieces_d::generate (rtx op0, rtx op1,
    1634              :                             machine_mode mode ATTRIBUTE_UNUSED)
    1635              : {
    1636              : #ifdef PUSH_ROUNDING
    1637      1654776 :   if (op0 == NULL_RTX)
    1638              :     {
    1639           47 :       emit_single_push_insn (mode, op1, NULL);
    1640           47 :       return;
    1641              :     }
    1642              : #endif
    1643      1654729 :   emit_insn (m_gen_fun (op0, op1));
    1644              : }
    1645              : 
    1646              : /* Perform the final adjustment at the end of a string to obtain the
    1647              :    correct return value for the block operation.
    1648              :    Return value is based on RETMODE argument.  */
    1649              : 
    1650              : rtx
    1651            0 : move_by_pieces_d::finish_retmode (memop_ret retmode)
    1652              : {
    1653            0 :   gcc_assert (!m_reverse);
    1654            0 :   if (retmode == RETURN_END_MINUS_ONE)
    1655              :     {
    1656            0 :       m_to.maybe_postinc (-1);
    1657            0 :       --m_offset;
    1658              :     }
    1659            0 :   return m_to.adjust (QImode, m_offset);
    1660              : }
    1661              : 
    1662              : /* Generate several move instructions to copy LEN bytes from block FROM to
    1663              :    block TO.  (These are MEM rtx's with BLKmode).
    1664              : 
    1665              :    If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
    1666              :    used to push FROM to the stack.
    1667              : 
    1668              :    ALIGN is maximum stack alignment we can assume.
    1669              : 
    1670              :    Return value is based on RETMODE argument.  */
    1671              : 
    1672              : rtx
    1673       571527 : move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
    1674              :                 unsigned int align, memop_ret retmode)
    1675              : {
    1676              : #ifndef PUSH_ROUNDING
    1677              :   if (to == NULL)
    1678              :     gcc_unreachable ();
    1679              : #endif
    1680              : 
    1681       571527 :   move_by_pieces_d data (to, from, len, align);
    1682              : 
    1683       571527 :   data.run ();
    1684              : 
    1685       571527 :   if (retmode != RETURN_BEGIN)
    1686            0 :     return data.finish_retmode (retmode);
    1687              :   else
    1688              :     return to;
    1689              : }
    1690              : 
    1691              : /* Derived class from op_by_pieces_d, providing support for block move
    1692              :    operations.  */
    1693              : 
    1694              : class store_by_pieces_d : public op_by_pieces_d
    1695              : {
    1696              :   insn_gen_fn m_gen_fun;
    1697              : 
    1698              :   void generate (rtx, rtx, machine_mode) final override;
    1699              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1700              : 
    1701              :  public:
    1702       125306 :   store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
    1703              :                      unsigned HOST_WIDE_INT len, unsigned int align,
    1704              :                      by_pieces_operation op)
    1705       125306 :     : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
    1706       250612 :                       cfn_data, len, align, false, op)
    1707              :   {
    1708       125306 :   }
    1709              :   rtx finish_retmode (memop_ret);
    1710              : };
    1711              : 
    1712              : /* Return true if MODE can be used for a set of stores, given an
    1713              :    alignment ALIGN.  Prepare whatever data is necessary for later
    1714              :    calls to generate.  */
    1715              : 
    1716              : bool
    1717       199831 : store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1718              : {
    1719       199831 :   insn_code icode = optab_handler (mov_optab, mode);
    1720       199831 :   m_gen_fun = GEN_FCN (icode);
    1721       199831 :   return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
    1722              : }
    1723              : 
    1724              : /* A callback used when iterating for a store_by_pieces_operation.
    1725              :    OP0 and OP1 are the values that have been loaded and should be
    1726              :    compared in MODE.  If OP0 is NULL, this means we should generate a
    1727              :    push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
    1728              :    gen function that should be used to generate the mode.  */
    1729              : 
    1730              : void
    1731       318966 : store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
    1732              : {
    1733       318966 :   emit_insn (m_gen_fun (op0, op1));
    1734       318966 : }
    1735              : 
    1736              : /* Perform the final adjustment at the end of a string to obtain the
    1737              :    correct return value for the block operation.
    1738              :    Return value is based on RETMODE argument.  */
    1739              : 
    1740              : rtx
    1741          647 : store_by_pieces_d::finish_retmode (memop_ret retmode)
    1742              : {
    1743          647 :   gcc_assert (!m_reverse);
    1744          647 :   if (retmode == RETURN_END_MINUS_ONE)
    1745              :     {
    1746           23 :       m_to.maybe_postinc (-1);
    1747           23 :       --m_offset;
    1748              :     }
    1749          647 :   return m_to.adjust (QImode, m_offset);
    1750              : }
    1751              : 
    1752              : /* Determine whether the LEN bytes generated by CONSTFUN can be
    1753              :    stored to memory using several move instructions.  CONSTFUNDATA is
    1754              :    a pointer which will be passed as argument in every CONSTFUN call.
    1755              :    ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
    1756              :    a memset operation and false if it's a copy of a constant string.
    1757              :    Return true if a call to store_by_pieces should succeed.  */
    1758              : 
    1759              : bool
    1760        91245 : can_store_by_pieces (unsigned HOST_WIDE_INT len,
    1761              :                      by_pieces_constfn constfun,
    1762              :                      void *constfundata, unsigned int align, bool memsetp)
    1763              : {
    1764        91245 :   unsigned HOST_WIDE_INT l;
    1765        91245 :   unsigned int max_size;
    1766        91245 :   HOST_WIDE_INT offset = 0;
    1767        91245 :   enum insn_code icode;
    1768        91245 :   int reverse;
    1769              :   /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it.  */
    1770        91245 :   rtx cst ATTRIBUTE_UNUSED;
    1771              : 
    1772        91245 :   if (len == 0)
    1773              :     return true;
    1774              : 
    1775       138093 :   if (!targetm.use_by_pieces_infrastructure_p (len, align,
    1776              :                                                memsetp
    1777              :                                                  ? SET_BY_PIECES
    1778              :                                                  : STORE_BY_PIECES,
    1779              :                                                optimize_insn_for_speed_p ()))
    1780              :     return false;
    1781              : 
    1782        54049 :   align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
    1783              : 
    1784              :   /* We would first store what we can in the largest integer mode, then go to
    1785              :      successively smaller modes.  */
    1786              : 
    1787        54049 :   for (reverse = 0;
    1788       108098 :        reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
    1789              :        reverse++)
    1790              :     {
    1791        54049 :       l = len;
    1792        54073 :       max_size = STORE_MAX_PIECES + 1;
    1793       255899 :       while (max_size > 1 && l > 0)
    1794              :         {
    1795       201850 :           auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
    1796       201850 :           auto mode = widest_fixed_size_mode_for_size (max_size, op);
    1797              : 
    1798       201850 :           icode = optab_handler (mov_optab, mode);
    1799       201850 :           if (icode != CODE_FOR_nothing
    1800       201850 :               && align >= GET_MODE_ALIGNMENT (mode))
    1801              :             {
    1802       201850 :               unsigned int size = GET_MODE_SIZE (mode);
    1803              : 
    1804       349129 :               while (l >= size)
    1805              :                 {
    1806       147279 :                   if (reverse)
    1807              :                     offset -= size;
    1808              : 
    1809       147279 :                   cst = (*constfun) (constfundata, nullptr, offset, mode);
    1810              :                   /* All CONST_VECTORs can be loaded for memset since
    1811              :                      vec_duplicate_optab is a precondition to pick a
    1812              :                      vector mode for the memset expander.  */
    1813       273739 :                   if (!((memsetp && VECTOR_MODE_P (mode))
    1814       126460 :                         || targetm.legitimate_constant_p (mode, cst)))
    1815        91245 :                     return false;
    1816              : 
    1817       147279 :                   if (!reverse)
    1818       147279 :                     offset += size;
    1819              : 
    1820       147279 :                   l -= size;
    1821              :                 }
    1822              :             }
    1823              : 
    1824       403700 :           max_size = GET_MODE_SIZE (mode);
    1825              :         }
    1826              : 
    1827              :       /* The code above should have handled everything.  */
    1828        54049 :       gcc_assert (!l);
    1829              :     }
    1830              : 
    1831              :   return true;
    1832              : }
    1833              : 
    1834              : /* Generate several move instructions to store LEN bytes generated by
    1835              :    CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
    1836              :    pointer which will be passed as argument in every CONSTFUN call.
    1837              :    ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
    1838              :    a memset operation and false if it's a copy of a constant string.
    1839              :    Return value is based on RETMODE argument.  */
    1840              : 
    1841              : rtx
    1842        61260 : store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
    1843              :                  by_pieces_constfn constfun,
    1844              :                  void *constfundata, unsigned int align, bool memsetp,
    1845              :                  memop_ret retmode)
    1846              : {
    1847        61260 :   if (len == 0)
    1848              :     {
    1849         7955 :       gcc_assert (retmode != RETURN_END_MINUS_ONE);
    1850              :       return to;
    1851              :     }
    1852              : 
    1853        95992 :   gcc_assert (targetm.use_by_pieces_infrastructure_p
    1854              :                 (len, align,
    1855              :                  memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
    1856              :                  optimize_insn_for_speed_p ()));
    1857              : 
    1858        53305 :   store_by_pieces_d data (to, constfun, constfundata, len, align,
    1859        53305 :                           memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
    1860        53305 :   data.run ();
    1861              : 
    1862        53305 :   if (retmode != RETURN_BEGIN)
    1863          647 :     return data.finish_retmode (retmode);
    1864              :   else
    1865              :     return to;
    1866              : }
    1867              : 
    1868              : void
    1869        72001 : clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
    1870              : {
    1871        72001 :   if (len == 0)
    1872              :     return;
    1873              : 
    1874              :   /* Use builtin_memset_read_str to support vector mode broadcast.  */
    1875        72001 :   char c = 0;
    1876        72001 :   store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
    1877        72001 :                           CLEAR_BY_PIECES);
    1878        72001 :   data.run ();
    1879              : }
    1880              : 
    1881              : /* Context used by compare_by_pieces_genfn.  It stores the fail label
    1882              :    to jump to in case of miscomparison, and for branch ratios greater than 1,
    1883              :    it stores an accumulator and the current and maximum counts before
    1884              :    emitting another branch.  */
    1885              : 
    1886              : class compare_by_pieces_d : public op_by_pieces_d
    1887              : {
    1888              :   rtx_code_label *m_fail_label;
    1889              :   rtx m_accumulator;
    1890              :   int m_count, m_batch;
    1891              : 
    1892              :   void generate (rtx, rtx, machine_mode) final override;
    1893              :   bool prepare_mode (machine_mode, unsigned int) final override;
    1894              :   void finish_mode (machine_mode) final override;
    1895              : 
    1896              :  public:
    1897        62848 :   compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
    1898              :                        void *op1_cfn_data, HOST_WIDE_INT len, int align,
    1899              :                        rtx_code_label *fail_label)
    1900        62848 :     : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
    1901       125696 :                       op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
    1902              :   {
    1903        62848 :     m_fail_label = fail_label;
    1904        62848 :   }
    1905              : };
    1906              : 
    1907              : /* A callback used when iterating for a compare_by_pieces_operation.
    1908              :    OP0 and OP1 are the values that have been loaded and should be
    1909              :    compared in MODE.  DATA holds a pointer to the compare_by_pieces_data
    1910              :    context structure.  */
    1911              : 
    1912              : void
    1913        98045 : compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
    1914              : {
    1915        98045 :   if (m_batch > 1)
    1916              :     {
    1917            0 :       rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
    1918              :                                true, OPTAB_LIB_WIDEN);
    1919            0 :       if (m_count != 0)
    1920            0 :         temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
    1921              :                              true, OPTAB_LIB_WIDEN);
    1922            0 :       m_accumulator = temp;
    1923              : 
    1924            0 :       if (++m_count < m_batch)
    1925              :         return;
    1926              : 
    1927            0 :       m_count = 0;
    1928            0 :       op0 = m_accumulator;
    1929            0 :       op1 = const0_rtx;
    1930            0 :       m_accumulator = NULL_RTX;
    1931              :     }
    1932        98045 :   do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
    1933              :                            m_fail_label, profile_probability::uninitialized ());
    1934              : }
    1935              : 
    1936              : /* Return true if MODE can be used for a set of moves and comparisons,
    1937              :    given an alignment ALIGN.  Prepare whatever data is necessary for
    1938              :    later calls to generate.  */
    1939              : 
    1940              : bool
    1941        94790 : compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
    1942              : {
    1943        94790 :   insn_code icode = optab_handler (mov_optab, mode);
    1944        94790 :   if (icode == CODE_FOR_nothing
    1945        94790 :       || align < GET_MODE_ALIGNMENT (mode)
    1946       189580 :       || !can_compare_p (EQ, mode, ccp_jump))
    1947              :     return false;
    1948        94790 :   m_batch = targetm.compare_by_pieces_branch_ratio (mode);
    1949        94790 :   if (m_batch < 0)
    1950              :     return false;
    1951        94790 :   m_accumulator = NULL_RTX;
    1952        94790 :   m_count = 0;
    1953        94790 :   return true;
    1954              : }
    1955              : 
    1956              : /* Called after expanding a series of comparisons in MODE.  If we have
    1957              :    accumulated results for which we haven't emitted a branch yet, do
    1958              :    so now.  */
    1959              : 
    1960              : void
    1961        94790 : compare_by_pieces_d::finish_mode (machine_mode mode)
    1962              : {
    1963        94790 :   if (m_accumulator != NULL_RTX)
    1964            0 :     do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
    1965              :                              NULL_RTX, NULL, m_fail_label,
    1966              :                              profile_probability::uninitialized ());
    1967        94790 : }
    1968              : 
    1969              : /* Generate several move instructions to compare LEN bytes from blocks
    1970              :    ARG0 and ARG1.  (These are MEM rtx's with BLKmode).
    1971              : 
    1972              :    If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
    1973              :    used to push FROM to the stack.
    1974              : 
    1975              :    ALIGN is maximum stack alignment we can assume.
    1976              : 
    1977              :    Optionally, the caller can pass a constfn and associated data in A1_CFN
    1978              :    and A1_CFN_DATA. describing that the second operand being compared is a
    1979              :    known constant and how to obtain its data.  */
    1980              : 
    1981              : static rtx
    1982        62848 : compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
    1983              :                    rtx target, unsigned int align,
    1984              :                    by_pieces_constfn a1_cfn, void *a1_cfn_data)
    1985              : {
    1986        62848 :   rtx_code_label *fail_label = gen_label_rtx ();
    1987        62848 :   rtx_code_label *end_label = gen_label_rtx ();
    1988              : 
    1989        62848 :   if (target == NULL_RTX
    1990        62848 :       || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
    1991            2 :     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
    1992              : 
    1993        62848 :   compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
    1994        62848 :                             fail_label);
    1995              : 
    1996        62848 :   data.run ();
    1997              : 
    1998        62848 :   emit_move_insn (target, const0_rtx);
    1999        62848 :   emit_jump (end_label);
    2000        62848 :   emit_barrier ();
    2001        62848 :   emit_label (fail_label);
    2002        62848 :   emit_move_insn (target, const1_rtx);
    2003        62848 :   emit_label (end_label);
    2004              : 
    2005        62848 :   return target;
    2006              : }
    2007              : 
    2008              : /* Emit code to move a block Y to a block X.  This may be done with
    2009              :    string-move instructions, with multiple scalar move instructions,
    2010              :    or with a library call.
    2011              : 
    2012              :    Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
    2013              :    SIZE is an rtx that says how long they are.
    2014              :    ALIGN is the maximum alignment we can assume they have.
    2015              :    METHOD describes what kind of copy this is, and what mechanisms may be used.
    2016              :    MIN_SIZE is the minimal size of block to move
    2017              :    MAX_SIZE is the maximal size of block to move, if it cannot be represented
    2018              :    in unsigned HOST_WIDE_INT, than it is mask of all ones.
    2019              :    CTZ_SIZE is the trailing-zeros count of SIZE; even a nonconstant SIZE is
    2020              :    known to be a multiple of 1<<CTZ_SIZE.
    2021              : 
    2022              :    Return the address of the new block, if memcpy is called and returns it,
    2023              :    0 otherwise.  */
    2024              : 
    2025              : rtx
    2026       671632 : emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
    2027              :                        unsigned int expected_align, HOST_WIDE_INT expected_size,
    2028              :                        unsigned HOST_WIDE_INT min_size,
    2029              :                        unsigned HOST_WIDE_INT max_size,
    2030              :                        unsigned HOST_WIDE_INT probable_max_size,
    2031              :                        bool bail_out_libcall, bool *is_move_done,
    2032              :                        bool might_overlap, unsigned ctz_size)
    2033              : {
    2034       671632 :   int may_use_call;
    2035       671632 :   rtx retval = 0;
    2036       671632 :   unsigned int align;
    2037              : 
    2038       671632 :   if (is_move_done)
    2039        98905 :     *is_move_done = true;
    2040              : 
    2041       671632 :   gcc_assert (size);
    2042       671632 :   if (CONST_INT_P (size) && INTVAL (size) == 0)
    2043              :     return 0;
    2044              : 
    2045       671355 :   switch (method)
    2046              :     {
    2047              :     case BLOCK_OP_NORMAL:
    2048              :     case BLOCK_OP_TAILCALL:
    2049              :       may_use_call = 1;
    2050              :       break;
    2051              : 
    2052       269069 :     case BLOCK_OP_CALL_PARM:
    2053       269069 :       may_use_call = block_move_libcall_safe_for_call_parm ();
    2054              : 
    2055              :       /* Make inhibit_defer_pop nonzero around the library call
    2056              :          to force it to pop the arguments right away.  */
    2057       269069 :       NO_DEFER_POP;
    2058       269069 :       break;
    2059              : 
    2060          354 :     case BLOCK_OP_NO_LIBCALL:
    2061          354 :       may_use_call = 0;
    2062          354 :       break;
    2063              : 
    2064         1074 :     case BLOCK_OP_NO_LIBCALL_RET:
    2065         1074 :       may_use_call = -1;
    2066         1074 :       break;
    2067              : 
    2068            0 :     default:
    2069            0 :       gcc_unreachable ();
    2070              :     }
    2071              : 
    2072       671355 :   gcc_assert (MEM_P (x) && MEM_P (y));
    2073       671440 :   align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
    2074       671355 :   gcc_assert (align >= BITS_PER_UNIT);
    2075              : 
    2076              :   /* Make sure we've got BLKmode addresses; store_one_arg can decide that
    2077              :      block copy is more efficient for other large modes, e.g. DCmode.  */
    2078       671355 :   x = adjust_address (x, BLKmode, 0);
    2079       671355 :   y = adjust_address (y, BLKmode, 0);
    2080              : 
    2081              :   /* If source and destination are the same, no need to copy anything.  */
    2082       671355 :   if (rtx_equal_p (x, y)
    2083           13 :       && !MEM_VOLATILE_P (x)
    2084       671368 :       && !MEM_VOLATILE_P (y))
    2085              :     return 0;
    2086              : 
    2087              :   /* Set MEM_SIZE as appropriate for this block copy.  The main place this
    2088              :      can be incorrect is coming from __builtin_memcpy.  */
    2089       671342 :   poly_int64 const_size;
    2090       671342 :   if (poly_int_rtx_p (size, &const_size))
    2091              :     {
    2092       591601 :       x = shallow_copy_rtx (x);
    2093       591601 :       y = shallow_copy_rtx (y);
    2094       591601 :       set_mem_size (x, const_size);
    2095       591601 :       set_mem_size (y, const_size);
    2096              :     }
    2097              : 
    2098       671342 :   bool pieces_ok = CONST_INT_P (size)
    2099       671342 :     && can_move_by_pieces (INTVAL (size), align);
    2100       671342 :   bool pattern_ok = false;
    2101              : 
    2102       671342 :   if (!pieces_ok || might_overlap)
    2103              :     {
    2104       106909 :       pattern_ok
    2105       106909 :         = emit_block_move_via_pattern (x, y, size, align,
    2106              :                                        expected_align, expected_size,
    2107              :                                        min_size, max_size, probable_max_size,
    2108              :                                        might_overlap);
    2109       106909 :       if (!pattern_ok && might_overlap)
    2110              :         {
    2111              :           /* Do not try any of the other methods below as they are not safe
    2112              :              for overlapping moves.  */
    2113        12815 :           *is_move_done = false;
    2114        12815 :           return retval;
    2115              :         }
    2116              :     }
    2117              : 
    2118        94094 :   bool dynamic_direction = false;
    2119        94094 :   if (!pattern_ok && !pieces_ok && may_use_call
    2120       136922 :       && (flag_inline_stringops & (might_overlap ? ILSOP_MEMMOVE : ILSOP_MEMCPY)))
    2121              :     {
    2122       658527 :       may_use_call = 0;
    2123       658527 :       dynamic_direction = might_overlap;
    2124              :     }
    2125              : 
    2126       658527 :   if (pattern_ok)
    2127              :     ;
    2128       632894 :   else if (pieces_ok)
    2129       564433 :     move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
    2130        68461 :   else if (may_use_call && !might_overlap
    2131        68410 :            && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
    2132       136871 :            && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
    2133              :     {
    2134        68410 :       if (bail_out_libcall)
    2135              :         {
    2136          259 :           if (is_move_done)
    2137          259 :             *is_move_done = false;
    2138              :           return retval;
    2139              :         }
    2140              : 
    2141        68151 :       if (may_use_call < 0)
    2142            0 :         return pc_rtx;
    2143              : 
    2144        68151 :       retval = emit_block_copy_via_libcall (x, y, size,
    2145              :                                             method == BLOCK_OP_TAILCALL);
    2146              :     }
    2147           51 :   else if (dynamic_direction)
    2148            0 :     emit_block_move_via_oriented_loop (x, y, size, align, ctz_size);
    2149           51 :   else if (might_overlap)
    2150            0 :     *is_move_done = false;
    2151              :   else
    2152           51 :     emit_block_move_via_sized_loop (x, y, size, align, ctz_size);
    2153              : 
    2154       658268 :   if (method == BLOCK_OP_CALL_PARM)
    2155       269058 :     OK_DEFER_POP;
    2156              : 
    2157              :   return retval;
    2158              : }
    2159              : 
    2160              : rtx
    2161       572727 : emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method,
    2162              :                  unsigned int ctz_size)
    2163              : {
    2164       572727 :   unsigned HOST_WIDE_INT max, min = 0;
    2165       572727 :   if (GET_CODE (size) == CONST_INT)
    2166       572507 :     min = max = UINTVAL (size);
    2167              :   else
    2168          220 :     max = GET_MODE_MASK (GET_MODE (size));
    2169       572727 :   return emit_block_move_hints (x, y, size, method, 0, -1,
    2170              :                                 min, max, max,
    2171       572727 :                                 false, NULL, false, ctz_size);
    2172              : }
    2173              : 
    2174              : /* A subroutine of emit_block_move.  Returns true if calling the
    2175              :    block move libcall will not clobber any parameters which may have
    2176              :    already been placed on the stack.  */
    2177              : 
    2178              : static bool
    2179       269069 : block_move_libcall_safe_for_call_parm (void)
    2180              : {
    2181       269069 :   tree fn;
    2182              : 
    2183              :   /* If arguments are pushed on the stack, then they're safe.  */
    2184       269069 :   if (targetm.calls.push_argument (0))
    2185              :     return true;
    2186              : 
    2187              :   /* If registers go on the stack anyway, any argument is sure to clobber
    2188              :      an outgoing argument.  */
    2189              : #if defined (REG_PARM_STACK_SPACE)
    2190            3 :   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    2191              :   /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
    2192              :      depend on its argument.  */
    2193            3 :   (void) fn;
    2194            3 :   if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
    2195            3 :       && REG_PARM_STACK_SPACE (fn) != 0)
    2196              :     return false;
    2197              : #endif
    2198              : 
    2199              :   /* If any argument goes in memory, then it might clobber an outgoing
    2200              :      argument.  */
    2201            3 :   {
    2202            3 :     CUMULATIVE_ARGS args_so_far_v;
    2203            3 :     cumulative_args_t args_so_far;
    2204            3 :     tree arg;
    2205              : 
    2206            3 :     fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    2207            3 :     INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
    2208            3 :     args_so_far = pack_cumulative_args (&args_so_far_v);
    2209              : 
    2210            3 :     arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
    2211           12 :     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
    2212              :       {
    2213            9 :         machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
    2214            9 :         function_arg_info arg_info (mode, /*named=*/true);
    2215            9 :         rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
    2216            9 :         if (!tmp || !REG_P (tmp))
    2217            0 :           return false;
    2218            9 :         if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
    2219              :           return false;
    2220            9 :         targetm.calls.function_arg_advance (args_so_far, arg_info);
    2221              :       }
    2222              :   }
    2223            3 :   return true;
    2224              : }
    2225              : 
    2226              : /* A subroutine of emit_block_move.  Expand a cpymem or movmem pattern;
    2227              :    return true if successful.
    2228              : 
    2229              :    X is the destination of the copy or move.
    2230              :    Y is the source of the copy or move.
    2231              :    SIZE is the size of the block to be moved.
    2232              : 
    2233              :    MIGHT_OVERLAP indicates this originated with expansion of a
    2234              :    builtin_memmove() and the source and destination blocks may
    2235              :    overlap.
    2236              :   */
    2237              : 
    2238              : static bool
    2239       106909 : emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
    2240              :                              unsigned int expected_align,
    2241              :                              HOST_WIDE_INT expected_size,
    2242              :                              unsigned HOST_WIDE_INT min_size,
    2243              :                              unsigned HOST_WIDE_INT max_size,
    2244              :                              unsigned HOST_WIDE_INT probable_max_size,
    2245              :                              bool might_overlap)
    2246              : {
    2247       106909 :   if (expected_align < align)
    2248              :     expected_align = align;
    2249       106909 :   if (expected_size != -1)
    2250              :     {
    2251           22 :       if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
    2252            0 :         expected_size = probable_max_size;
    2253           22 :       if ((unsigned HOST_WIDE_INT)expected_size < min_size)
    2254            0 :         expected_size = min_size;
    2255              :     }
    2256              : 
    2257              :   /* Since this is a move insn, we don't care about volatility.  */
    2258       106909 :   temporary_volatile_ok v (true);
    2259              : 
    2260              :   /* Try the most limited insn first, because there's no point
    2261              :      including more than one in the machine description unless
    2262              :      the more limited one has some advantage.  */
    2263              : 
    2264       106909 :   opt_scalar_int_mode mode_iter;
    2265       731108 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    2266              :     {
    2267       649832 :       scalar_int_mode mode = mode_iter.require ();
    2268       649832 :       enum insn_code code;
    2269       649832 :       if (might_overlap)
    2270       103890 :         code = direct_optab_handler (movmem_optab, mode);
    2271              :       else
    2272       545942 :         code = direct_optab_handler (cpymem_optab, mode);
    2273              : 
    2274       649832 :       if (code != CODE_FOR_nothing
    2275              :           /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
    2276              :              here because if SIZE is less than the mode mask, as it is
    2277              :              returned by the macro, it will definitely be less than the
    2278              :              actual mode mask.  Since SIZE is within the Pmode address
    2279              :              space, we limit MODE to Pmode.  */
    2280       649832 :           && ((CONST_INT_P (size)
    2281        42071 :                && ((unsigned HOST_WIDE_INT) INTVAL (size)
    2282        42071 :                    <= (GET_MODE_MASK (mode) >> 1)))
    2283       145079 :               || max_size <= (GET_MODE_MASK (mode) >> 1)
    2284       181800 :               || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
    2285              :         {
    2286       123741 :           class expand_operand ops[9];
    2287       123741 :           unsigned int nops;
    2288              : 
    2289              :           /* ??? When called via emit_block_move_for_call, it'd be
    2290              :              nice if there were some way to inform the backend, so
    2291              :              that it doesn't fail the expansion because it thinks
    2292              :              emitting the libcall would be more efficient.  */
    2293       123741 :           nops = insn_data[(int) code].n_generator_args;
    2294       123741 :           gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
    2295              : 
    2296       123741 :           create_fixed_operand (&ops[0], x);
    2297       123741 :           create_fixed_operand (&ops[1], y);
    2298              :           /* The check above guarantees that this size conversion is valid.  */
    2299       123741 :           create_convert_operand_to (&ops[2], size, mode, true);
    2300       123741 :           create_integer_operand (&ops[3], align / BITS_PER_UNIT);
    2301       123741 :           if (nops >= 6)
    2302              :             {
    2303       123741 :               create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
    2304       123741 :               create_integer_operand (&ops[5], expected_size);
    2305              :             }
    2306       123741 :           if (nops >= 8)
    2307              :             {
    2308       123741 :               create_integer_operand (&ops[6], min_size);
    2309              :               /* If we cannot represent the maximal size,
    2310              :                  make parameter NULL.  */
    2311       123741 :               if ((HOST_WIDE_INT) max_size != -1)
    2312       105984 :                 create_integer_operand (&ops[7], max_size);
    2313              :               else
    2314        17757 :                 create_fixed_operand (&ops[7], NULL);
    2315              :             }
    2316       123741 :           if (nops == 9)
    2317              :             {
    2318              :               /* If we cannot represent the maximal size,
    2319              :                  make parameter NULL.  */
    2320       123741 :               if ((HOST_WIDE_INT) probable_max_size != -1)
    2321       108068 :                 create_integer_operand (&ops[8], probable_max_size);
    2322              :               else
    2323        15673 :                 create_fixed_operand (&ops[8], NULL);
    2324              :             }
    2325       123741 :           gcc_assert (min_size != max_size
    2326              :                       || rtx_equal_p (ops[2].value, GEN_INT (min_size)));
    2327       123741 :           if (maybe_expand_insn (code, nops, ops))
    2328        25633 :             return true;
    2329              :         }
    2330              :     }
    2331              : 
    2332              :   return false;
    2333       106909 : }
    2334              : 
    2335              : /* Like emit_block_move_via_loop, but choose a suitable INCR based on
    2336              :    ALIGN and CTZ_SIZE.  */
    2337              : 
    2338              : static void
    2339           51 : emit_block_move_via_sized_loop (rtx x, rtx y, rtx size,
    2340              :                                 unsigned int align,
    2341              :                                 unsigned int ctz_size)
    2342              : {
    2343           51 :   int incr = align / BITS_PER_UNIT;
    2344              : 
    2345           51 :   if (CONST_INT_P (size))
    2346            3 :     ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
    2347              : 
    2348           51 :   if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
    2349            0 :     incr = HOST_WIDE_INT_1U << ctz_size;
    2350              : 
    2351           51 :   while (incr > 1 && !can_move_by_pieces (incr, align))
    2352            0 :     incr >>= 1;
    2353              : 
    2354           51 :   gcc_checking_assert (incr);
    2355              : 
    2356           51 :   return emit_block_move_via_loop (x, y, size, align, incr);
    2357              : }
    2358              : 
    2359              : /* Like emit_block_move_via_sized_loop, but besides choosing INCR so
    2360              :    as to ensure safe moves even in case of overlap, output dynamic
    2361              :    tests to choose between two loops, one moving downwards, another
    2362              :    moving upwards.  */
    2363              : 
    2364              : static void
    2365            0 : emit_block_move_via_oriented_loop (rtx x, rtx y, rtx size,
    2366              :                                    unsigned int align,
    2367              :                                    unsigned int ctz_size)
    2368              : {
    2369            0 :   int incr = align / BITS_PER_UNIT;
    2370              : 
    2371            0 :   if (CONST_INT_P (size))
    2372            0 :     ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
    2373              : 
    2374            0 :   if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
    2375            0 :     incr = HOST_WIDE_INT_1U << ctz_size;
    2376              : 
    2377            0 :   while (incr > 1 && !int_mode_for_size (incr, 0).exists ())
    2378            0 :     incr >>= 1;
    2379              : 
    2380            0 :   gcc_checking_assert (incr);
    2381              : 
    2382            0 :   rtx_code_label *upw_label, *end_label;
    2383            0 :   upw_label = gen_label_rtx ();
    2384            0 :   end_label = gen_label_rtx ();
    2385              : 
    2386            0 :   rtx x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2387            0 :   rtx y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2388            0 :   do_pending_stack_adjust ();
    2389              : 
    2390            0 :   machine_mode mode = GET_MODE (x_addr);
    2391            0 :   if (mode != GET_MODE (y_addr))
    2392              :     {
    2393            0 :       scalar_int_mode xmode
    2394            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE (mode)).require ();
    2395            0 :       scalar_int_mode ymode
    2396            0 :         = smallest_int_mode_for_size (GET_MODE_BITSIZE
    2397            0 :                                       (GET_MODE (y_addr))).require ();
    2398            0 :       if (GET_MODE_BITSIZE (xmode) < GET_MODE_BITSIZE (ymode))
    2399              :         mode = ymode;
    2400              :       else
    2401            0 :         mode = xmode;
    2402              : 
    2403              : #ifndef POINTERS_EXTEND_UNSIGNED
    2404              :       const int POINTERS_EXTEND_UNSIGNED = 1;
    2405              : #endif
    2406            0 :       x_addr = convert_modes (mode, GET_MODE (x_addr), x_addr,
    2407              :                               POINTERS_EXTEND_UNSIGNED);
    2408            0 :       y_addr = convert_modes (mode, GET_MODE (y_addr), y_addr,
    2409              :                               POINTERS_EXTEND_UNSIGNED);
    2410              :     }
    2411              : 
    2412              :   /* Test for overlap: if (x >= y || x + size <= y) goto upw_label.  */
    2413            0 :   emit_cmp_and_jump_insns (x_addr, y_addr, GEU, NULL_RTX, mode,
    2414              :                            true, upw_label,
    2415            0 :                            profile_probability::guessed_always ()
    2416              :                                 .apply_scale (5, 10));
    2417            0 :   rtx tmp = convert_modes (GET_MODE (x_addr), GET_MODE (size), size, true);
    2418            0 :   tmp = simplify_gen_binary (PLUS, GET_MODE (x_addr), x_addr, tmp);
    2419              : 
    2420            0 :   emit_cmp_and_jump_insns (tmp, y_addr, LEU, NULL_RTX, mode,
    2421              :                            true, upw_label,
    2422            0 :                            profile_probability::guessed_always ()
    2423              :                                 .apply_scale (8, 10));
    2424              : 
    2425            0 :   emit_block_move_via_loop (x, y, size, align, -incr);
    2426              : 
    2427            0 :   emit_jump (end_label);
    2428            0 :   emit_label (upw_label);
    2429              : 
    2430            0 :   emit_block_move_via_loop (x, y, size, align, incr);
    2431              : 
    2432            0 :   emit_label (end_label);
    2433            0 : }
    2434              : 
    2435              : /* A subroutine of emit_block_move.  Copy the data via an explicit
    2436              :    loop.  This is used only when libcalls are forbidden, or when
    2437              :    inlining is required.  INCR is the block size to be copied in each
    2438              :    loop iteration.  If it is negative, the absolute value is used, and
    2439              :    the block is copied backwards.  INCR must be a power of two, an
    2440              :    exact divisor for SIZE and ALIGN, and imply a mode that can be
    2441              :    safely copied per iteration assuming no overlap.  */
    2442              : 
    2443              : static void
    2444           51 : emit_block_move_via_loop (rtx x, rtx y, rtx size,
    2445              :                           unsigned int align, int incr)
    2446              : {
    2447           51 :   rtx_code_label *cmp_label, *top_label;
    2448           51 :   rtx iter, x_addr, y_addr, tmp;
    2449           51 :   machine_mode x_addr_mode = get_address_mode (x);
    2450           51 :   machine_mode y_addr_mode = get_address_mode (y);
    2451           51 :   machine_mode iter_mode;
    2452              : 
    2453           51 :   iter_mode = GET_MODE (size);
    2454           51 :   if (iter_mode == VOIDmode)
    2455            3 :     iter_mode = word_mode;
    2456              : 
    2457           51 :   top_label = gen_label_rtx ();
    2458           51 :   cmp_label = gen_label_rtx ();
    2459           51 :   iter = gen_reg_rtx (iter_mode);
    2460              : 
    2461           51 :   bool downwards = incr < 0;
    2462           51 :   rtx iter_init;
    2463           51 :   rtx_code iter_cond;
    2464           51 :   rtx iter_limit;
    2465           51 :   rtx iter_incr;
    2466           51 :   machine_mode move_mode;
    2467           51 :   if (downwards)
    2468              :     {
    2469            0 :       incr = -incr;
    2470            0 :       iter_init = size;
    2471            0 :       iter_cond = GEU;
    2472            0 :       iter_limit = const0_rtx;
    2473            0 :       iter_incr = GEN_INT (incr);
    2474              :     }
    2475              :   else
    2476              :     {
    2477           51 :       iter_init = const0_rtx;
    2478           51 :       iter_cond = LTU;
    2479           51 :       iter_limit = size;
    2480           51 :       iter_incr = GEN_INT (incr);
    2481              :     }
    2482           51 :   emit_move_insn (iter, iter_init);
    2483              : 
    2484           51 :   opt_scalar_int_mode int_move_mode
    2485           51 :     = int_mode_for_size (incr * BITS_PER_UNIT, 1);
    2486           51 :   if (!int_move_mode.exists (&move_mode)
    2487          102 :       || GET_MODE_BITSIZE (int_move_mode.require ()) != incr * BITS_PER_UNIT)
    2488              :     {
    2489            0 :       move_mode = BLKmode;
    2490            0 :       gcc_checking_assert (can_move_by_pieces (incr, align));
    2491              :     }
    2492              : 
    2493           51 :   x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2494           51 :   y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2495           51 :   do_pending_stack_adjust ();
    2496              : 
    2497           51 :   emit_jump (cmp_label);
    2498           51 :   emit_label (top_label);
    2499              : 
    2500           51 :   tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
    2501           51 :   x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
    2502              : 
    2503           51 :   if (x_addr_mode != y_addr_mode)
    2504            0 :     tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
    2505           51 :   y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
    2506              : 
    2507           51 :   x = change_address (x, move_mode, x_addr);
    2508           51 :   y = change_address (y, move_mode, y_addr);
    2509              : 
    2510           51 :   if (move_mode == BLKmode)
    2511              :     {
    2512            0 :       bool done;
    2513            0 :       emit_block_move_hints (x, y, iter_incr, BLOCK_OP_NO_LIBCALL,
    2514              :                              align, incr, incr, incr, incr,
    2515              :                              false, &done, false);
    2516            0 :       gcc_checking_assert (done);
    2517              :     }
    2518              :   else
    2519           51 :     emit_move_insn (x, y);
    2520              : 
    2521           51 :   if (downwards)
    2522            0 :     emit_label (cmp_label);
    2523              : 
    2524           51 :   tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
    2525              :                              true, OPTAB_LIB_WIDEN);
    2526           51 :   if (tmp != iter)
    2527            0 :     emit_move_insn (iter, tmp);
    2528              : 
    2529           51 :   if (!downwards)
    2530           51 :     emit_label (cmp_label);
    2531              : 
    2532           51 :   emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
    2533              :                            true, top_label,
    2534           51 :                            profile_probability::guessed_always ()
    2535              :                                 .apply_scale (9, 10));
    2536           51 : }
    2537              : 
    2538              : /* Expand a call to memcpy or memmove or memcmp, and return the result.
    2539              :    TAILCALL is true if this is a tail call.  */
    2540              : 
    2541              : rtx
    2542        68152 : emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
    2543              :                            rtx size, bool tailcall)
    2544              : {
    2545        68152 :   rtx dst_addr, src_addr;
    2546        68152 :   tree call_expr, dst_tree, src_tree, size_tree;
    2547        68152 :   machine_mode size_mode;
    2548              : 
    2549              :   /* Since dst and src are passed to a libcall, mark the corresponding
    2550              :      tree EXPR as addressable.  */
    2551        68152 :   tree dst_expr = MEM_EXPR (dst);
    2552        68152 :   tree src_expr = MEM_EXPR (src);
    2553        68152 :   if (dst_expr)
    2554        61433 :     mark_addressable (dst_expr);
    2555        68152 :   if (src_expr)
    2556        66740 :     mark_addressable (src_expr);
    2557              : 
    2558        68152 :   dst_addr = copy_addr_to_reg (XEXP (dst, 0));
    2559        68152 :   dst_addr = convert_memory_address (ptr_mode, dst_addr);
    2560        68152 :   dst_tree = make_tree (ptr_type_node, dst_addr);
    2561              : 
    2562        68152 :   src_addr = copy_addr_to_reg (XEXP (src, 0));
    2563        68152 :   src_addr = convert_memory_address (ptr_mode, src_addr);
    2564        68152 :   src_tree = make_tree (ptr_type_node, src_addr);
    2565              : 
    2566        68152 :   size_mode = TYPE_MODE (sizetype);
    2567        68152 :   size = convert_to_mode (size_mode, size, 1);
    2568        68152 :   size = copy_to_mode_reg (size_mode, size);
    2569        68152 :   size_tree = make_tree (sizetype, size);
    2570              : 
    2571              :   /* It is incorrect to use the libcall calling conventions for calls to
    2572              :      memcpy/memmove/memcmp because they can be provided by the user.  */
    2573        68152 :   tree fn = builtin_decl_implicit (fncode);
    2574        68152 :   call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
    2575        68152 :   CALL_EXPR_TAILCALL (call_expr) = tailcall;
    2576              : 
    2577        68152 :   return expand_call (call_expr, NULL_RTX, false);
    2578              : }
    2579              : 
    2580              : /* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
    2581              :    ARG3_TYPE is the type of ARG3_RTX.  Return the result rtx on success,
    2582              :    otherwise return null.  */
    2583              : 
    2584              : rtx
    2585       171601 : expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
    2586              :                           rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
    2587              :                           HOST_WIDE_INT align)
    2588              : {
    2589       171601 :   machine_mode insn_mode = insn_data[icode].operand[0].mode;
    2590              : 
    2591       171601 :   if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
    2592              :     target = NULL_RTX;
    2593              : 
    2594       171601 :   class expand_operand ops[5];
    2595       171601 :   create_output_operand (&ops[0], target, insn_mode);
    2596       171601 :   create_fixed_operand (&ops[1], arg1_rtx);
    2597       171601 :   create_fixed_operand (&ops[2], arg2_rtx);
    2598       171601 :   create_convert_operand_from (&ops[3], arg3_rtx, TYPE_MODE (arg3_type),
    2599       171601 :                                TYPE_UNSIGNED (arg3_type));
    2600       171601 :   create_integer_operand (&ops[4], align);
    2601       171601 :   if (maybe_expand_insn (icode, 5, ops))
    2602         5800 :     return ops[0].value;
    2603              :   return NULL_RTX;
    2604              : }
    2605              : 
    2606              : /* Expand a block compare between X and Y with length LEN using the
    2607              :    cmpmem optab, placing the result in TARGET.  LEN_TYPE is the type
    2608              :    of the expression that was used to calculate the length.  ALIGN
    2609              :    gives the known minimum common alignment.  */
    2610              : 
    2611              : static rtx
    2612        43663 : emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2613              :                            unsigned align)
    2614              : {
    2615              :   /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
    2616              :      implementing memcmp because it will stop if it encounters two
    2617              :      zero bytes.  */
    2618        43663 :   insn_code icode = direct_optab_handler (cmpmem_optab, SImode);
    2619              : 
    2620        43663 :   if (icode == CODE_FOR_nothing)
    2621              :     return NULL_RTX;
    2622              : 
    2623        43663 :   return expand_cmpstrn_or_cmpmem (icode, target, x, y, len_type, len, align);
    2624              : }
    2625              : 
    2626              : /* Emit code to compare a block Y to a block X.  This may be done with
    2627              :    string-compare instructions, with multiple scalar instructions,
    2628              :    or with a library call.
    2629              : 
    2630              :    Both X and Y must be MEM rtx's.  LEN is an rtx that says how long
    2631              :    they are.  LEN_TYPE is the type of the expression that was used to
    2632              :    calculate it, and CTZ_LEN is the known trailing-zeros count of LEN,
    2633              :    so LEN must be a multiple of 1<<CTZ_LEN even if it's not constant.
    2634              : 
    2635              :    If EQUALITY_ONLY is true, it means we don't have to return the tri-state
    2636              :    value of a normal memcmp call, instead we can just compare for equality.
    2637              :    If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
    2638              :    returning NULL_RTX.
    2639              : 
    2640              :    Optionally, the caller can pass a constfn and associated data in Y_CFN
    2641              :    and Y_CFN_DATA. describing that the second operand being compared is a
    2642              :    known constant and how to obtain its data.
    2643              :    Return the result of the comparison, or NULL_RTX if we failed to
    2644              :    perform the operation.  */
    2645              : 
    2646              : rtx
    2647       106510 : emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2648              :                       bool equality_only, by_pieces_constfn y_cfn,
    2649              :                       void *y_cfndata, unsigned ctz_len)
    2650              : {
    2651       106510 :   rtx result = 0;
    2652              : 
    2653       106510 :   if (CONST_INT_P (len) && INTVAL (len) == 0)
    2654            0 :     return const0_rtx;
    2655              : 
    2656       106510 :   gcc_assert (MEM_P (x) && MEM_P (y));
    2657       106510 :   unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
    2658       106510 :   gcc_assert (align >= BITS_PER_UNIT);
    2659              : 
    2660       106510 :   x = adjust_address (x, BLKmode, 0);
    2661       106510 :   y = adjust_address (y, BLKmode, 0);
    2662              : 
    2663       106510 :   if (equality_only
    2664        91625 :       && CONST_INT_P (len)
    2665       176118 :       && can_do_by_pieces (INTVAL (len), align, COMPARE_BY_PIECES))
    2666        62847 :     result = compare_by_pieces (x, y, INTVAL (len), target, align,
    2667              :                                 y_cfn, y_cfndata);
    2668              :   else
    2669        43663 :     result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
    2670              : 
    2671       106510 :   if (!result && (flag_inline_stringops & ILSOP_MEMCMP))
    2672          364 :     result = emit_block_cmp_via_loop (x, y, len, len_type,
    2673              :                                       target, equality_only,
    2674              :                                       align, ctz_len);
    2675              : 
    2676              :   return result;
    2677              : }
    2678              : 
    2679              : /* Like emit_block_cmp_hints, but with known alignment and no support
    2680              :    for constats.  Always expand to a loop with iterations that compare
    2681              :    blocks of the largest compare-by-pieces size that divides both len
    2682              :    and align, and then, if !EQUALITY_ONLY, identify the word and then
    2683              :    the unit that first differs to return the result.  */
    2684              : 
    2685              : rtx
    2686          406 : emit_block_cmp_via_loop (rtx x, rtx y, rtx len, tree len_type, rtx target,
    2687              :                          bool equality_only, unsigned align, unsigned ctz_len)
    2688              : {
    2689          406 :   unsigned incr = align / BITS_PER_UNIT;
    2690              : 
    2691          406 :   if (CONST_INT_P (len))
    2692          322 :     ctz_len = MAX (ctz_len, (unsigned) wi::ctz (UINTVAL (len)));
    2693              : 
    2694          406 :   if (HOST_WIDE_INT_1U << ctz_len < (unsigned HOST_WIDE_INT) incr)
    2695          148 :     incr = HOST_WIDE_INT_1U << ctz_len;
    2696              : 
    2697              :   while (incr > 1
    2698          410 :          && !can_do_by_pieces (incr, align, COMPARE_BY_PIECES))
    2699            4 :     incr >>= 1;
    2700              : 
    2701          406 :   rtx_code_label *cmp_label, *top_label, *ne_label, *res_label;
    2702          406 :   rtx iter, x_addr, y_addr, tmp;
    2703          406 :   machine_mode x_addr_mode = get_address_mode (x);
    2704          406 :   machine_mode y_addr_mode = get_address_mode (y);
    2705          406 :   machine_mode iter_mode;
    2706              : 
    2707          406 :   iter_mode = GET_MODE (len);
    2708          406 :   if (iter_mode == VOIDmode)
    2709          322 :     iter_mode = word_mode;
    2710              : 
    2711          406 :   rtx iter_init = const0_rtx;
    2712          406 :   rtx_code iter_cond = LTU;
    2713          406 :   rtx_code entry_cond = GEU;
    2714          406 :   rtx iter_limit = len;
    2715          406 :   rtx iter_incr = GEN_INT (incr);
    2716          406 :   machine_mode cmp_mode;
    2717              : 
    2718              :   /* We can drop the loop back edge if we know there's exactly one
    2719              :      iteration.  */
    2720          406 :   top_label = (!rtx_equal_p (len, iter_incr)
    2721          406 :                ? gen_label_rtx ()
    2722              :                : NULL);
    2723              :   /* We need not test before entering the loop if len is known
    2724              :      nonzero.  ??? This could be even stricter, testing whether a
    2725              :      nonconstant LEN could possibly be zero.  */
    2726          406 :   cmp_label = (!CONSTANT_P (len) || rtx_equal_p (len, iter_init)
    2727          406 :                ? gen_label_rtx ()
    2728              :                : NULL);
    2729          406 :   ne_label = gen_label_rtx ();
    2730          406 :   res_label = gen_label_rtx ();
    2731              : 
    2732          406 :   iter = gen_reg_rtx (iter_mode);
    2733          406 :   emit_move_insn (iter, iter_init);
    2734              : 
    2735          406 :   opt_scalar_int_mode int_cmp_mode
    2736          406 :     = int_mode_for_size (incr * BITS_PER_UNIT, 1);
    2737          406 :   if (!int_cmp_mode.exists (&cmp_mode)
    2738         1216 :       || GET_MODE_BITSIZE (int_cmp_mode.require ()) != incr * BITS_PER_UNIT
    2739          405 :       || !can_compare_p (NE, cmp_mode, ccp_jump))
    2740              :     {
    2741            1 :       cmp_mode = BLKmode;
    2742            1 :       gcc_checking_assert (incr != 1);
    2743              :     }
    2744              : 
    2745              :   /* Save the base addresses.  */
    2746          406 :   x_addr = force_operand (XEXP (x, 0), NULL_RTX);
    2747          406 :   y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    2748          406 :   do_pending_stack_adjust ();
    2749              : 
    2750          406 :   if (cmp_label)
    2751              :     {
    2752           84 :       if (top_label)
    2753           84 :         emit_jump (cmp_label);
    2754              :       else
    2755            0 :         emit_cmp_and_jump_insns (iter, iter_limit, entry_cond,
    2756              :                                  NULL_RTX, iter_mode,
    2757              :                                  true, cmp_label,
    2758            0 :                                  profile_probability::guessed_always ()
    2759              :                                  .apply_scale (1, 10));
    2760              :     }
    2761          406 :   if (top_label)
    2762          389 :     emit_label (top_label);
    2763              : 
    2764              :   /* Offset the base addresses by ITER.  */
    2765          406 :   tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
    2766          406 :   x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
    2767              : 
    2768          406 :   if (x_addr_mode != y_addr_mode)
    2769            0 :     tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
    2770          406 :   y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
    2771              : 
    2772          406 :   x = change_address (x, cmp_mode, x_addr);
    2773          406 :   y = change_address (y, cmp_mode, y_addr);
    2774              : 
    2775              :   /* Compare one block.  */
    2776          406 :   rtx part_res;
    2777          406 :   if (cmp_mode == BLKmode)
    2778            1 :     part_res = compare_by_pieces (x, y, incr, target, align, 0, 0);
    2779              :   else
    2780          405 :     part_res = expand_binop (cmp_mode, sub_optab, x, y, NULL_RTX,
    2781              :                              true, OPTAB_LIB_WIDEN);
    2782              : 
    2783              :   /* Stop if we found a difference.  */
    2784          812 :   emit_cmp_and_jump_insns (part_res, GEN_INT (0), NE, NULL_RTX,
    2785          406 :                            GET_MODE (part_res), true, ne_label,
    2786          406 :                            profile_probability::guessed_always ()
    2787              :                                 .apply_scale (1, 10));
    2788              : 
    2789              :   /* Increment ITER.  */
    2790          406 :   tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
    2791              :                              true, OPTAB_LIB_WIDEN);
    2792          406 :   if (tmp != iter)
    2793            0 :     emit_move_insn (iter, tmp);
    2794              : 
    2795          406 :   if (cmp_label)
    2796           84 :     emit_label (cmp_label);
    2797              :   /* Loop until we reach the limit.  */
    2798              : 
    2799          406 :   if (top_label)
    2800          389 :     emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
    2801              :                              true, top_label,
    2802          778 :                              profile_probability::guessed_always ()
    2803              :                              .apply_scale (9, 10));
    2804              : 
    2805              :   /* We got to the end without differences, so the result is zero.  */
    2806          406 :   if (target == NULL_RTX
    2807          406 :       || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
    2808           49 :     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
    2809              : 
    2810          406 :   emit_move_insn (target, const0_rtx);
    2811          406 :   emit_jump (res_label);
    2812              : 
    2813          406 :   emit_label (ne_label);
    2814              : 
    2815              :   /* Return nonzero, or pinpoint the difference to return the expected
    2816              :      result for non-equality tests.  */
    2817          406 :   if (equality_only)
    2818            0 :     emit_move_insn (target, const1_rtx);
    2819              :   else
    2820              :     {
    2821          406 :       if (incr > UNITS_PER_WORD)
    2822              :         /* ??? Re-compare the block found to be different one word at a
    2823              :            time.  */
    2824            5 :         part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
    2825              :                                             target, equality_only,
    2826              :                                             BITS_PER_WORD, 0);
    2827          401 :       else if (incr > 1)
    2828              :         /* ??? Re-compare the block found to be different one byte at a
    2829              :            time.  We could do better using part_res, and being careful
    2830              :            about endianness.  */
    2831           37 :         part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
    2832              :                                             target, equality_only,
    2833              :                                             BITS_PER_UNIT, 0);
    2834         1092 :       else if (known_gt (GET_MODE_BITSIZE (GET_MODE (target)),
    2835              :                          GET_MODE_BITSIZE (cmp_mode)))
    2836          364 :         part_res = expand_binop (GET_MODE (target), sub_optab, x, y, target,
    2837              :                                  true, OPTAB_LIB_WIDEN);
    2838              :       else
    2839              :         {
    2840              :           /* In the odd chance target is QImode, we can't count on
    2841              :              widening subtract to capture the result of the unsigned
    2842              :              compares.  */
    2843            0 :           rtx_code_label *ltu_label;
    2844            0 :           ltu_label = gen_label_rtx ();
    2845            0 :           emit_cmp_and_jump_insns (x, y, LTU, NULL_RTX,
    2846              :                                    cmp_mode, true, ltu_label,
    2847            0 :                                    profile_probability::guessed_always ()
    2848              :                                    .apply_scale (5, 10));
    2849              : 
    2850            0 :           emit_move_insn (target, const1_rtx);
    2851            0 :           emit_jump (res_label);
    2852              : 
    2853            0 :           emit_label (ltu_label);
    2854            0 :           emit_move_insn (target, constm1_rtx);
    2855            0 :           part_res = target;
    2856              :         }
    2857              : 
    2858          406 :       if (target != part_res)
    2859            0 :         convert_move (target, part_res, false);
    2860              :     }
    2861              : 
    2862          406 :   emit_label (res_label);
    2863              : 
    2864          406 :   return target;
    2865              : }
    2866              : 
    2867              : 
    2868              : /* Copy all or part of a value X into registers starting at REGNO.
    2869              :    The number of registers to be filled is NREGS.  */
    2870              : 
    2871              : void
    2872          434 : move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
    2873              : {
    2874          434 :   if (nregs == 0)
    2875              :     return;
    2876              : 
    2877          420 :   if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
    2878            0 :     x = validize_mem (force_const_mem (mode, x));
    2879              : 
    2880              :   /* See if the machine can do this with a load multiple insn.  */
    2881          420 :   if (targetm.have_load_multiple ())
    2882              :     {
    2883            0 :       rtx_insn *last = get_last_insn ();
    2884            0 :       rtx first = gen_rtx_REG (word_mode, regno);
    2885            0 :       if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
    2886              :                                                      GEN_INT (nregs)))
    2887              :         {
    2888            0 :           emit_insn (pat);
    2889            0 :           return;
    2890              :         }
    2891              :       else
    2892            0 :         delete_insns_since (last);
    2893              :     }
    2894              : 
    2895          848 :   for (int i = 0; i < nregs; i++)
    2896          428 :     emit_move_insn (gen_rtx_REG (word_mode, regno + i),
    2897          428 :                     operand_subword_force (x, i, mode));
    2898              : }
    2899              : 
    2900              : /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
    2901              :    The number of registers to be filled is NREGS.  */
    2902              : 
    2903              : void
    2904         1216 : move_block_from_reg (int regno, rtx x, int nregs)
    2905              : {
    2906         1216 :   if (nregs == 0)
    2907              :     return;
    2908              : 
    2909              :   /* See if the machine can do this with a store multiple insn.  */
    2910         1216 :   if (targetm.have_store_multiple ())
    2911              :     {
    2912            0 :       rtx_insn *last = get_last_insn ();
    2913            0 :       rtx first = gen_rtx_REG (word_mode, regno);
    2914            0 :       if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
    2915              :                                                       GEN_INT (nregs)))
    2916              :         {
    2917            0 :           emit_insn (pat);
    2918            0 :           return;
    2919              :         }
    2920              :       else
    2921            0 :         delete_insns_since (last);
    2922              :     }
    2923              : 
    2924         2436 :   for (int i = 0; i < nregs; i++)
    2925              :     {
    2926         1220 :       rtx tem = operand_subword (x, i, 1, BLKmode);
    2927              : 
    2928         1220 :       gcc_assert (tem);
    2929              : 
    2930         1220 :       emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
    2931              :     }
    2932              : }
    2933              : 
    2934              : /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
    2935              :    ORIG, where ORIG is a non-consecutive group of registers represented by
    2936              :    a PARALLEL.  The clone is identical to the original except in that the
    2937              :    original set of registers is replaced by a new set of pseudo registers.
    2938              :    The new set has the same modes as the original set.  */
    2939              : 
    2940              : rtx
    2941         3305 : gen_group_rtx (rtx orig)
    2942              : {
    2943         3305 :   int i, length;
    2944         3305 :   rtx *tmps;
    2945              : 
    2946         3305 :   gcc_assert (GET_CODE (orig) == PARALLEL);
    2947              : 
    2948         3305 :   length = XVECLEN (orig, 0);
    2949         3305 :   tmps = XALLOCAVEC (rtx, length);
    2950              : 
    2951              :   /* Skip a NULL entry in first slot.  */
    2952         3305 :   i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
    2953              : 
    2954         3305 :   if (i)
    2955            0 :     tmps[0] = 0;
    2956              : 
    2957         8052 :   for (; i < length; i++)
    2958              :     {
    2959         4747 :       machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
    2960         4747 :       rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
    2961              : 
    2962         4747 :       tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
    2963              :     }
    2964              : 
    2965         3305 :   return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
    2966              : }
    2967              : 
    2968              : /* A subroutine of emit_group_load.  Arguments as for emit_group_load,
    2969              :    except that values are placed in TMPS[i], and must later be moved
    2970              :    into corresponding XEXP (XVECEXP (DST, 0, i), 0) element.  */
    2971              : 
    2972              : static void
    2973       298188 : emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
    2974              :                    poly_int64 ssize)
    2975              : {
    2976       298191 :   rtx src;
    2977       298191 :   int start, i;
    2978       298191 :   machine_mode m = GET_MODE (orig_src);
    2979              : 
    2980       298191 :   gcc_assert (GET_CODE (dst) == PARALLEL);
    2981              : 
    2982       298191 :   if (m != VOIDmode
    2983       279334 :       && !SCALAR_INT_MODE_P (m)
    2984        19423 :       && !MEM_P (orig_src)
    2985         5708 :       && GET_CODE (orig_src) != CONCAT)
    2986              :     {
    2987            3 :       scalar_int_mode imode;
    2988            3 :       if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode))
    2989              :         {
    2990            3 :           src = gen_reg_rtx (imode);
    2991            3 :           emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
    2992              :         }
    2993              :       else
    2994              :         {
    2995            0 :           src = assign_stack_temp (GET_MODE (orig_src), ssize);
    2996            0 :           emit_move_insn (src, orig_src);
    2997              :         }
    2998            3 :       emit_group_load_1 (tmps, dst, src, type, ssize);
    2999              :       return;
    3000              :     }
    3001              : 
    3002              :   /* Check for a NULL entry, used to indicate that the parameter goes
    3003              :      both on the stack and in registers.  */
    3004       298188 :   if (XEXP (XVECEXP (dst, 0, 0), 0))
    3005              :     start = 0;
    3006              :   else
    3007            0 :     start = 1;
    3008              : 
    3009              :   /* Process the pieces.  */
    3010       882932 :   for (i = start; i < XVECLEN (dst, 0); i++)
    3011              :     {
    3012       584744 :       machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
    3013       584744 :       poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
    3014      1169488 :       poly_int64 bytelen = GET_MODE_SIZE (mode);
    3015       584744 :       poly_int64 shift = 0;
    3016              : 
    3017              :       /* Handle trailing fragments that run over the size of the struct.
    3018              :          It's the target's responsibility to make sure that the fragment
    3019              :          cannot be strictly smaller in some cases and strictly larger
    3020              :          in others.  */
    3021       584744 :       gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
    3022       584744 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3023              :         {
    3024              :           /* Arrange to shift the fragment to where it belongs.
    3025              :              extract_bit_field loads to the lsb of the reg.  */
    3026              :           if (
    3027              : #ifdef BLOCK_REG_PADDING
    3028              :               BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
    3029              :               == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
    3030              : #else
    3031              :               BYTES_BIG_ENDIAN
    3032              : #endif
    3033              :               )
    3034              :             shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
    3035         1831 :           bytelen = ssize - bytepos;
    3036         1831 :           gcc_assert (maybe_gt (bytelen, 0));
    3037              :         }
    3038              : 
    3039              :       /* If we won't be loading directly from memory, protect the real source
    3040              :          from strange tricks we might play; but make sure that the source can
    3041              :          be loaded directly into the destination.  */
    3042       584744 :       src = orig_src;
    3043       584744 :       if (!MEM_P (orig_src)
    3044       483199 :           && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
    3045        46359 :           && GET_CODE (orig_src) != CONCAT
    3046       622458 :           && !CONSTANT_P (orig_src))
    3047              :         {
    3048            0 :           gcc_assert (GET_MODE (orig_src) != VOIDmode);
    3049            0 :           src = force_reg (GET_MODE (orig_src), orig_src);
    3050              :         }
    3051              : 
    3052              :       /* Optimize the access just a bit.  */
    3053       584744 :       if (MEM_P (src)
    3054       101545 :           && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
    3055            0 :               || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
    3056       203090 :           && multiple_p (bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
    3057       686289 :           && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3058              :         {
    3059        99733 :           tmps[i] = gen_reg_rtx (mode);
    3060        99733 :           emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
    3061              :         }
    3062       485011 :       else if (COMPLEX_MODE_P (mode)
    3063            0 :                && GET_MODE (src) == mode
    3064       485011 :                && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3065              :         /* Let emit_move_complex do the bulk of the work.  */
    3066            0 :         tmps[i] = src;
    3067       485011 :       else if (SCALAR_INT_MODE_P (mode)
    3068       478504 :                && COMPLEX_MODE_P (GET_MODE (src))
    3069         9396 :                && known_eq (GET_MODE_SIZE (mode),
    3070              :                             GET_MODE_SIZE (GET_MODE (src)))
    3071       487757 :                && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3072              :         {
    3073              :           /* When passing a complex value in an integer mode of the same
    3074              :              size, explicitly construct (highpart<<isize)+lowpart to
    3075              :              avoid spilling to memory before reload.  */
    3076         2746 :           rtx tmp = read_complex_part (src, !BYTES_BIG_ENDIAN);
    3077         2746 :           scalar_int_mode imode = int_mode_for_mode (GET_MODE (tmp)).require();
    3078         2746 :           tmp = gen_lowpart (imode, tmp);
    3079         2746 :           tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
    3080         2746 :           rtx result = force_reg (mode, tmp);
    3081         5492 :           result = expand_shift (LSHIFT_EXPR, mode, result,
    3082         2746 :                                  GET_MODE_BITSIZE (imode), NULL_RTX, 1);
    3083         2746 :           tmp = read_complex_part (src, BYTES_BIG_ENDIAN);
    3084         2746 :           tmp = gen_lowpart (imode, tmp);
    3085         2746 :           tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
    3086         2746 :           result = simplify_gen_binary (PLUS, mode, result, tmp);
    3087         2746 :           tmps[i] = force_reg (mode, result);
    3088              :         }
    3089       482265 :       else if (GET_CODE (src) == CONCAT)
    3090              :         {
    3091        11798 :           poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
    3092        11798 :           poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
    3093         5899 :           unsigned int elt;
    3094         5899 :           poly_int64 subpos;
    3095              : 
    3096         5899 :           if (can_div_trunc_p (bytepos, slen0, &elt, &subpos)
    3097         5899 :               && known_le (subpos + bytelen, slen0))
    3098              :             {
    3099              :               /* The following assumes that the concatenated objects all
    3100              :                  have the same size.  In this case, a simple calculation
    3101              :                  can be used to determine the object and the bit field
    3102              :                  to be extracted.  */
    3103         5880 :               tmps[i] = XEXP (src, elt);
    3104         5880 :               if (maybe_ne (subpos, 0)
    3105         5880 :                   || maybe_ne (subpos + bytelen, slen0)
    3106        11760 :                   || (!CONSTANT_P (tmps[i])
    3107         5880 :                       && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
    3108            0 :                 tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
    3109            0 :                                              subpos * BITS_PER_UNIT,
    3110              :                                              1, NULL_RTX, mode, mode, false,
    3111              :                                              NULL);
    3112              :             }
    3113              :           else
    3114              :             {
    3115           19 :               rtx mem;
    3116              : 
    3117           19 :               gcc_assert (known_eq (bytepos, 0));
    3118           19 :               mem = assign_stack_temp (GET_MODE (src), slen);
    3119           19 :               emit_move_insn (mem, src);
    3120           19 :               tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
    3121              :                                            0, 1, NULL_RTX, mode, mode, false,
    3122              :                                            NULL);
    3123              :             }
    3124              :         }
    3125       476366 :       else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
    3126        37714 :                && XVECLEN (dst, 0) > 1)
    3127        37714 :         tmps[i] = force_subreg (mode, src, GET_MODE (dst), bytepos);
    3128       438652 :       else if (CONSTANT_P (src))
    3129              :         {
    3130            0 :           if (known_eq (bytelen, ssize))
    3131            0 :             tmps[i] = src;
    3132              :           else
    3133              :             {
    3134              :               rtx first, second;
    3135              : 
    3136              :               /* TODO: const_wide_int can have sizes other than this...  */
    3137            0 :               gcc_assert (known_eq (2 * bytelen, ssize));
    3138            0 :               split_double (src, &first, &second);
    3139            0 :               if (i)
    3140            0 :                 tmps[i] = second;
    3141              :               else
    3142            0 :                 tmps[i] = first;
    3143              :             }
    3144              :         }
    3145       438652 :       else if (REG_P (src) && GET_MODE (src) == mode)
    3146            0 :         tmps[i] = src;
    3147              :       else
    3148       438652 :         tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
    3149       877304 :                                      bytepos * BITS_PER_UNIT, 1, NULL_RTX,
    3150              :                                      mode, mode, false, NULL);
    3151              : 
    3152       584744 :       if (maybe_ne (shift, 0))
    3153              :         tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
    3154              :                                 shift, tmps[i], 0);
    3155              :     }
    3156              : }
    3157              : 
    3158              : /* Emit code to move a block SRC of type TYPE to a block DST,
    3159              :    where DST is non-consecutive registers represented by a PARALLEL.
    3160              :    SSIZE represents the total size of block ORIG_SRC in bytes, or -1
    3161              :    if not known.  */
    3162              : 
    3163              : void
    3164        10983 : emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
    3165              : {
    3166        10983 :   rtx *tmps;
    3167        10983 :   int i;
    3168              : 
    3169        10983 :   tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
    3170        10983 :   emit_group_load_1 (tmps, dst, src, type, ssize);
    3171              : 
    3172              :   /* Copy the extracted pieces into the proper (probable) hard regs.  */
    3173        41585 :   for (i = 0; i < XVECLEN (dst, 0); i++)
    3174              :     {
    3175        19619 :       rtx d = XEXP (XVECEXP (dst, 0, i), 0);
    3176        19619 :       if (d == NULL)
    3177            0 :         continue;
    3178        19619 :       emit_move_insn (d, tmps[i]);
    3179              :     }
    3180        10983 : }
    3181              : 
    3182              : /* Similar, but load SRC into new pseudos in a format that looks like
    3183              :    PARALLEL.  This can later be fed to emit_group_move to get things
    3184              :    in the right place.  */
    3185              : 
    3186              : rtx
    3187       287205 : emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
    3188              : {
    3189       287205 :   rtvec vec;
    3190       287205 :   int i;
    3191              : 
    3192       287205 :   vec = rtvec_alloc (XVECLEN (parallel, 0));
    3193       287205 :   emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
    3194              : 
    3195              :   /* Convert the vector to look just like the original PARALLEL, except
    3196              :      with the computed values.  */
    3197      1139535 :   for (i = 0; i < XVECLEN (parallel, 0); i++)
    3198              :     {
    3199       565125 :       rtx e = XVECEXP (parallel, 0, i);
    3200       565125 :       rtx d = XEXP (e, 0);
    3201              : 
    3202       565125 :       if (d)
    3203              :         {
    3204       565125 :           d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
    3205       565125 :           e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
    3206              :         }
    3207       565125 :       RTVEC_ELT (vec, i) = e;
    3208              :     }
    3209              : 
    3210       287205 :   return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
    3211              : }
    3212              : 
    3213              : /* Emit code to move a block SRC to block DST, where SRC and DST are
    3214              :    non-consecutive groups of registers, each represented by a PARALLEL.  */
    3215              : 
    3216              : void
    3217       290510 : emit_group_move (rtx dst, rtx src)
    3218              : {
    3219       290510 :   int i;
    3220              : 
    3221       290510 :   gcc_assert (GET_CODE (src) == PARALLEL
    3222              :               && GET_CODE (dst) == PARALLEL
    3223              :               && XVECLEN (src, 0) == XVECLEN (dst, 0));
    3224              : 
    3225              :   /* Skip first entry if NULL.  */
    3226       860382 :   for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
    3227       569872 :     emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
    3228       569872 :                     XEXP (XVECEXP (src, 0, i), 0));
    3229       290510 : }
    3230              : 
    3231              : /* Move a group of registers represented by a PARALLEL into pseudos.  */
    3232              : 
    3233              : rtx
    3234         5820 : emit_group_move_into_temps (rtx src)
    3235              : {
    3236         5820 :   rtvec vec = rtvec_alloc (XVECLEN (src, 0));
    3237         5820 :   int i;
    3238              : 
    3239        19515 :   for (i = 0; i < XVECLEN (src, 0); i++)
    3240              :     {
    3241         7875 :       rtx e = XVECEXP (src, 0, i);
    3242         7875 :       rtx d = XEXP (e, 0);
    3243              : 
    3244         7875 :       if (d)
    3245         7875 :         e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
    3246         7875 :       RTVEC_ELT (vec, i) = e;
    3247              :     }
    3248              : 
    3249         5820 :   return gen_rtx_PARALLEL (GET_MODE (src), vec);
    3250              : }
    3251              : 
    3252              : /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
    3253              :    where SRC is non-consecutive registers represented by a PARALLEL.
    3254              :    SSIZE represents the total size of block ORIG_DST, or -1 if not
    3255              :    known.  */
    3256              : 
    3257              : void
    3258        65741 : emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
    3259              :                   poly_int64 ssize)
    3260              : {
    3261        65741 :   rtx *tmps, dst;
    3262        65741 :   int start, finish, i;
    3263        65741 :   machine_mode m = GET_MODE (orig_dst);
    3264              : 
    3265        65741 :   gcc_assert (GET_CODE (src) == PARALLEL);
    3266              : 
    3267        65741 :   if (!SCALAR_INT_MODE_P (m)
    3268        14579 :       && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
    3269              :     {
    3270            0 :       scalar_int_mode imode;
    3271            0 :       if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode))
    3272              :         {
    3273            0 :           dst = gen_reg_rtx (imode);
    3274            0 :           emit_group_store (dst, src, type, ssize);
    3275            0 :           dst = gen_lowpart (GET_MODE (orig_dst), dst);
    3276              :         }
    3277              :       else
    3278              :         {
    3279            0 :           dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
    3280            0 :           emit_group_store (dst, src, type, ssize);
    3281              :         }
    3282            0 :       emit_move_insn (orig_dst, dst);
    3283            0 :       return;
    3284              :     }
    3285              : 
    3286              :   /* Check for a NULL entry, used to indicate that the parameter goes
    3287              :      both on the stack and in registers.  */
    3288        65741 :   if (XEXP (XVECEXP (src, 0, 0), 0))
    3289              :     start = 0;
    3290              :   else
    3291            0 :     start = 1;
    3292        65741 :   finish = XVECLEN (src, 0);
    3293              : 
    3294        65741 :   tmps = XALLOCAVEC (rtx, finish);
    3295              : 
    3296              :   /* Copy the (probable) hard regs into pseudos.  */
    3297       188874 :   for (i = start; i < finish; i++)
    3298              :     {
    3299       123133 :       rtx reg = XEXP (XVECEXP (src, 0, i), 0);
    3300       123133 :       if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
    3301              :         {
    3302       115258 :           tmps[i] = gen_reg_rtx (GET_MODE (reg));
    3303       115258 :           emit_move_insn (tmps[i], reg);
    3304              :         }
    3305              :       else
    3306         7875 :         tmps[i] = reg;
    3307              :     }
    3308              : 
    3309              :   /* If we won't be storing directly into memory, protect the real destination
    3310              :      from strange tricks we might play.  */
    3311        65741 :   dst = orig_dst;
    3312        65741 :   if (GET_CODE (dst) == PARALLEL)
    3313              :     {
    3314            0 :       rtx temp;
    3315              : 
    3316              :       /* We can get a PARALLEL dst if there is a conditional expression in
    3317              :          a return statement.  In that case, the dst and src are the same,
    3318              :          so no action is necessary.  */
    3319            0 :       if (rtx_equal_p (dst, src))
    3320              :         return;
    3321              : 
    3322              :       /* It is unclear if we can ever reach here, but we may as well handle
    3323              :          it.  Allocate a temporary, and split this into a store/load to/from
    3324              :          the temporary.  */
    3325            0 :       temp = assign_stack_temp (GET_MODE (dst), ssize);
    3326            0 :       emit_group_store (temp, src, type, ssize);
    3327            0 :       emit_group_load (dst, temp, type, ssize);
    3328            0 :       return;
    3329              :     }
    3330        65741 :   else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
    3331              :     {
    3332        50528 :       machine_mode outer = GET_MODE (dst);
    3333        50528 :       machine_mode inner;
    3334        50528 :       poly_int64 bytepos;
    3335        50528 :       bool done = false;
    3336        50528 :       rtx temp;
    3337              : 
    3338        50528 :       if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
    3339            0 :         dst = gen_reg_rtx (outer);
    3340              : 
    3341              :       /* Make life a bit easier for combine: if the first element of the
    3342              :          vector is the low part of the destination mode, use a paradoxical
    3343              :          subreg to initialize the destination.  */
    3344        50528 :       if (start < finish)
    3345              :         {
    3346        50528 :           inner = GET_MODE (tmps[start]);
    3347        50528 :           bytepos = subreg_lowpart_offset (inner, outer);
    3348        50528 :           if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
    3349              :                         bytepos))
    3350              :             {
    3351        50504 :               temp = force_subreg (outer, tmps[start], inner, 0);
    3352        50504 :               if (temp)
    3353              :                 {
    3354        49836 :                   emit_move_insn (dst, temp);
    3355        49836 :                   done = true;
    3356        49836 :                   start++;
    3357              :                 }
    3358              :             }
    3359              :         }
    3360              : 
    3361              :       /* If the first element wasn't the low part, try the last.  */
    3362        49836 :       if (!done
    3363          692 :           && start < finish - 1)
    3364              :         {
    3365          625 :           inner = GET_MODE (tmps[finish - 1]);
    3366          625 :           bytepos = subreg_lowpart_offset (inner, outer);
    3367          625 :           if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
    3368              :                                                           finish - 1), 1)),
    3369              :                         bytepos))
    3370              :             {
    3371            0 :               temp = force_subreg (outer, tmps[finish - 1], inner, 0);
    3372            0 :               if (temp)
    3373              :                 {
    3374            0 :                   emit_move_insn (dst, temp);
    3375            0 :                   done = true;
    3376            0 :                   finish--;
    3377              :                 }
    3378              :             }
    3379              :         }
    3380              : 
    3381              :       /* Otherwise, simply initialize the result to zero.  */
    3382        49836 :       if (!done)
    3383          692 :         emit_move_insn (dst, CONST0_RTX (outer));
    3384              :     }
    3385              : 
    3386              :   /* Process the pieces.  */
    3387       135469 :   for (i = start; i < finish; i++)
    3388              :     {
    3389        73297 :       poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
    3390        73297 :       machine_mode mode = GET_MODE (tmps[i]);
    3391       146594 :       poly_int64 bytelen = GET_MODE_SIZE (mode);
    3392        73297 :       poly_uint64 adj_bytelen;
    3393        73297 :       rtx dest = dst;
    3394              : 
    3395              :       /* Handle trailing fragments that run over the size of the struct.
    3396              :          It's the target's responsibility to make sure that the fragment
    3397              :          cannot be strictly smaller in some cases and strictly larger
    3398              :          in others.  */
    3399        73297 :       gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
    3400       145647 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3401          947 :         adj_bytelen = ssize - bytepos;
    3402              :       else
    3403        73297 :         adj_bytelen = bytelen;
    3404              : 
    3405              :       /* Deal with destination CONCATs by either storing into one of the parts
    3406              :          or doing a copy after storing into a register or stack temporary.  */
    3407        73297 :       if (GET_CODE (dst) == CONCAT)
    3408              :         {
    3409        28982 :           if (known_le (bytepos + adj_bytelen,
    3410              :                         GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
    3411              :             dest = XEXP (dst, 0);
    3412              : 
    3413        18060 :           else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
    3414              :             {
    3415        10922 :               bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
    3416         5461 :               dest = XEXP (dst, 1);
    3417              :             }
    3418              : 
    3419              :           else
    3420              :             {
    3421         3569 :               machine_mode dest_mode = GET_MODE (dest);
    3422         3569 :               machine_mode tmp_mode = GET_MODE (tmps[i]);
    3423         3569 :               scalar_int_mode dest_imode;
    3424              : 
    3425         3569 :               gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
    3426              : 
    3427              :               /* If the source is a single scalar integer register, and the
    3428              :                  destination has a complex mode for which a same-sized integer
    3429              :                  mode exists, then we can take the left-justified part of the
    3430              :                  source in the complex mode.  */
    3431         3569 :               if (finish == start + 1
    3432         3569 :                   && REG_P (tmps[i])
    3433         3569 :                   && SCALAR_INT_MODE_P (tmp_mode)
    3434         3569 :                   && COMPLEX_MODE_P (dest_mode)
    3435         7138 :                   && int_mode_for_mode (dest_mode).exists (&dest_imode))
    3436              :                 {
    3437         3569 :                   const scalar_int_mode tmp_imode
    3438         3569 :                     = as_a <scalar_int_mode> (tmp_mode);
    3439              : 
    3440         7138 :                   if (GET_MODE_BITSIZE (dest_imode)
    3441         3569 :                       < GET_MODE_BITSIZE (tmp_imode))
    3442              :                     {
    3443           59 :                       dest = gen_reg_rtx (dest_imode);
    3444           59 :                       if (BYTES_BIG_ENDIAN)
    3445              :                         tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
    3446              :                                                 GET_MODE_BITSIZE (tmp_imode)
    3447              :                                                 - GET_MODE_BITSIZE (dest_imode),
    3448              :                                                 NULL_RTX, 1);
    3449           59 :                       emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
    3450           59 :                       dst = gen_lowpart (dest_mode, dest);
    3451              :                     }
    3452              :                   else
    3453         3510 :                     dst = gen_lowpart (dest_mode, tmps[i]);
    3454              :                 }
    3455              : 
    3456              :               /* Otherwise spill the source onto the stack using the more
    3457              :                  aligned of the two modes.  */
    3458            0 :               else if (GET_MODE_ALIGNMENT (dest_mode)
    3459            0 :                        >= GET_MODE_ALIGNMENT (tmp_mode))
    3460              :                 {
    3461            0 :                   dest = assign_stack_temp (dest_mode,
    3462            0 :                                             GET_MODE_SIZE (dest_mode));
    3463            0 :                   emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
    3464              :                                   tmps[i]);
    3465            0 :                   dst = dest;
    3466              :                 }
    3467              : 
    3468              :               else
    3469              :                 {
    3470            0 :                   dest = assign_stack_temp (tmp_mode,
    3471            0 :                                             GET_MODE_SIZE (tmp_mode));
    3472            0 :                   emit_move_insn (dest, tmps[i]);
    3473            0 :                   dst = adjust_address (dest, dest_mode, bytepos);
    3474              :                 }
    3475              : 
    3476              :               break;
    3477              :             }
    3478              :         }
    3479              : 
    3480              :       /* Handle trailing fragments that run over the size of the struct.  */
    3481        69728 :       if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
    3482              :         {
    3483              :           /* store_bit_field always takes its value from the lsb.
    3484              :              Move the fragment to the lsb if it's not already there.  */
    3485          888 :           if (
    3486              : #ifdef BLOCK_REG_PADDING
    3487              :               BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
    3488              :               == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
    3489              : #else
    3490              :               BYTES_BIG_ENDIAN
    3491              : #endif
    3492              :               )
    3493              :             {
    3494              :               poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
    3495              :               tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
    3496              :                                       shift, tmps[i], 0);
    3497              :             }
    3498              : 
    3499              :           /* Make sure not to write past the end of the struct.  */
    3500          888 :           store_bit_field (dest,
    3501          888 :                            adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
    3502         3552 :                            bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
    3503              :                            VOIDmode, tmps[i], false, false);
    3504              :         }
    3505              : 
    3506              :       /* Optimize the access just a bit.  */
    3507        68840 :       else if (MEM_P (dest)
    3508         7598 :                && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
    3509            0 :                    || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
    3510        15196 :                && multiple_p (bytepos * BITS_PER_UNIT,
    3511              :                               GET_MODE_ALIGNMENT (mode))
    3512        76438 :                && known_eq (bytelen, GET_MODE_SIZE (mode)))
    3513         7598 :         emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
    3514              : 
    3515              :       else
    3516       122484 :         store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
    3517              :                          0, 0, mode, tmps[i], false, false);
    3518              :     }
    3519              : 
    3520              :   /* Copy from the pseudo into the (probable) hard reg.  */
    3521        65741 :   if (orig_dst != dst)
    3522         3569 :     emit_move_insn (orig_dst, dst);
    3523              : }
    3524              : 
    3525              : /* Return a form of X that does not use a PARALLEL.  TYPE is the type
    3526              :    of the value stored in X.  */
    3527              : 
    3528              : rtx
    3529       339211 : maybe_emit_group_store (rtx x, tree type)
    3530              : {
    3531       339211 :   machine_mode mode = TYPE_MODE (type);
    3532       339211 :   gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
    3533       339211 :   if (GET_CODE (x) == PARALLEL)
    3534              :     {
    3535            0 :       rtx result = gen_reg_rtx (mode);
    3536            0 :       emit_group_store (result, x, type, int_size_in_bytes (type));
    3537            0 :       return result;
    3538              :     }
    3539              :   return x;
    3540              : }
    3541              : 
    3542              : /* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
    3543              : 
    3544              :    This is used on targets that return BLKmode values in registers.  */
    3545              : 
    3546              : static void
    3547          256 : copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
    3548              : {
    3549          256 :   unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
    3550          256 :   rtx src = NULL, dst = NULL;
    3551          256 :   unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
    3552          256 :   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
    3553              :   /* No current ABI uses variable-sized modes to pass a BLKmnode type.  */
    3554          256 :   fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
    3555          256 :   fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
    3556          256 :   fixed_size_mode copy_mode;
    3557              : 
    3558              :   /* BLKmode registers created in the back-end shouldn't have survived.  */
    3559          256 :   gcc_assert (mode != BLKmode);
    3560              : 
    3561              :   /* If the structure doesn't take up a whole number of words, see whether
    3562              :      SRCREG is padded on the left or on the right.  If it's on the left,
    3563              :      set PADDING_CORRECTION to the number of bits to skip.
    3564              : 
    3565              :      In most ABIs, the structure will be returned at the least end of
    3566              :      the register, which translates to right padding on little-endian
    3567              :      targets and left padding on big-endian targets.  The opposite
    3568              :      holds if the structure is returned at the most significant
    3569              :      end of the register.  */
    3570          256 :   if (bytes % UNITS_PER_WORD != 0
    3571          256 :       && (targetm.calls.return_in_msb (type)
    3572          225 :           ? !BYTES_BIG_ENDIAN
    3573              :           : BYTES_BIG_ENDIAN))
    3574            0 :     padding_correction
    3575            0 :       = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
    3576              : 
    3577              :   /* We can use a single move if we have an exact mode for the size.  */
    3578          256 :   else if (MEM_P (target)
    3579          256 :            && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
    3580            0 :                || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
    3581          512 :            && bytes == GET_MODE_SIZE (mode))
    3582              :   {
    3583           38 :     emit_move_insn (adjust_address (target, mode, 0), srcreg);
    3584           38 :     return;
    3585              :   }
    3586              : 
    3587              :   /* And if we additionally have the same mode for a register.  */
    3588          218 :   else if (REG_P (target)
    3589            0 :            && GET_MODE (target) == mode
    3590          218 :            && bytes == GET_MODE_SIZE (mode))
    3591              :   {
    3592            0 :     emit_move_insn (target, srcreg);
    3593            0 :     return;
    3594              :   }
    3595              : 
    3596              :   /* This code assumes srcreg is at least a full word.  If it isn't, copy it
    3597              :      into a new pseudo which is a full word.  */
    3598          436 :   if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
    3599              :     {
    3600           77 :       srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
    3601           77 :       mode = word_mode;
    3602              :     }
    3603              : 
    3604              :   /* Copy the structure BITSIZE bits at a time.  If the target lives in
    3605              :      memory, take care of not reading/writing past its end by selecting
    3606              :      a copy mode suited to BITSIZE.  This should always be possible given
    3607              :      how it is computed.
    3608              : 
    3609              :      If the target lives in register, make sure not to select a copy mode
    3610              :      larger than the mode of the register.
    3611              : 
    3612              :      We could probably emit more efficient code for machines which do not use
    3613              :      strict alignment, but it doesn't seem worth the effort at the current
    3614              :      time.  */
    3615              : 
    3616          218 :   copy_mode = word_mode;
    3617          218 :   if (MEM_P (target))
    3618              :     {
    3619          218 :       opt_scalar_int_mode mem_mode = int_mode_for_size (bitsize, 1);
    3620          218 :       if (mem_mode.exists ())
    3621          218 :         copy_mode = mem_mode.require ();
    3622              :     }
    3623            0 :   else if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    3624              :     copy_mode = tmode;
    3625              : 
    3626          218 :   for (bitpos = 0, xbitpos = padding_correction;
    3627         1068 :        bitpos < bytes * BITS_PER_UNIT;
    3628          850 :        bitpos += bitsize, xbitpos += bitsize)
    3629              :     {
    3630              :       /* We need a new source operand each time xbitpos is on a
    3631              :          word boundary and when xbitpos == padding_correction
    3632              :          (the first time through).  */
    3633          850 :       if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
    3634          218 :         src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
    3635              : 
    3636              :       /* We need a new destination operand each time bitpos is on
    3637              :          a word boundary.  */
    3638          850 :       if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    3639              :         dst = target;
    3640          850 :       else if (bitpos % BITS_PER_WORD == 0)
    3641          218 :         dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
    3642              : 
    3643              :       /* Use xbitpos for the source extraction (right justified) and
    3644              :          bitpos for the destination store (left justified).  */
    3645          850 :       store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
    3646          850 :                        extract_bit_field (src, bitsize,
    3647          850 :                                           xbitpos % BITS_PER_WORD, 1,
    3648              :                                           NULL_RTX, copy_mode, copy_mode,
    3649              :                                           false, NULL),
    3650              :                        false, false);
    3651              :     }
    3652              : }
    3653              : 
    3654              : /* Copy BLKmode value SRC into a register of mode MODE_IN.  Return the
    3655              :    register if it contains any data, otherwise return null.
    3656              : 
    3657              :    This is used on targets that return BLKmode values in registers.  */
    3658              : 
    3659              : rtx
    3660         3681 : copy_blkmode_to_reg (machine_mode mode_in, tree src)
    3661              : {
    3662         3681 :   int i, n_regs;
    3663         3681 :   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
    3664         3681 :   unsigned int bitsize;
    3665         3681 :   rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
    3666              :   /* No current ABI uses variable-sized modes to pass a BLKmnode type.  */
    3667         3681 :   fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
    3668         3681 :   fixed_size_mode dst_mode;
    3669         3681 :   scalar_int_mode min_mode;
    3670              : 
    3671         3681 :   gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
    3672              : 
    3673         3681 :   x = expand_normal (src);
    3674              : 
    3675         3681 :   bytes = arg_int_size_in_bytes (TREE_TYPE (src));
    3676         3681 :   if (bytes == 0)
    3677              :     return NULL_RTX;
    3678              : 
    3679              :   /* If the structure doesn't take up a whole number of words, see
    3680              :      whether the register value should be padded on the left or on
    3681              :      the right.  Set PADDING_CORRECTION to the number of padding
    3682              :      bits needed on the left side.
    3683              : 
    3684              :      In most ABIs, the structure will be returned at the least end of
    3685              :      the register, which translates to right padding on little-endian
    3686              :      targets and left padding on big-endian targets.  The opposite
    3687              :      holds if the structure is returned at the most significant
    3688              :      end of the register.  */
    3689         1224 :   if (bytes % UNITS_PER_WORD != 0
    3690         1224 :       && (targetm.calls.return_in_msb (TREE_TYPE (src))
    3691         1188 :           ? !BYTES_BIG_ENDIAN
    3692              :           : BYTES_BIG_ENDIAN))
    3693            0 :     padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
    3694            0 :                                            * BITS_PER_UNIT));
    3695              : 
    3696         1224 :   n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
    3697         1224 :   dst_words = XALLOCAVEC (rtx, n_regs);
    3698         1224 :   bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
    3699         1224 :   min_mode = smallest_int_mode_for_size (bitsize).require ();
    3700              : 
    3701              :   /* Copy the structure BITSIZE bits at a time.  */
    3702         1224 :   for (bitpos = 0, xbitpos = padding_correction;
    3703         3974 :        bitpos < bytes * BITS_PER_UNIT;
    3704         2750 :        bitpos += bitsize, xbitpos += bitsize)
    3705              :     {
    3706              :       /* We need a new destination pseudo each time xbitpos is
    3707              :          on a word boundary and when xbitpos == padding_correction
    3708              :          (the first time through).  */
    3709         2750 :       if (xbitpos % BITS_PER_WORD == 0
    3710         1523 :           || xbitpos == padding_correction)
    3711              :         {
    3712              :           /* Generate an appropriate register.  */
    3713         1227 :           dst_word = gen_reg_rtx (word_mode);
    3714         1227 :           dst_words[xbitpos / BITS_PER_WORD] = dst_word;
    3715              : 
    3716              :           /* Clear the destination before we move anything into it.  */
    3717         1227 :           emit_move_insn (dst_word, CONST0_RTX (word_mode));
    3718              :         }
    3719              : 
    3720              :       /* Find the largest integer mode that can be used to copy all or as
    3721              :          many bits as possible of the structure if the target supports larger
    3722              :          copies.  There are too many corner cases here w.r.t to alignments on
    3723              :          the read/writes.  So if there is any padding just use single byte
    3724              :          operations.  */
    3725         2750 :       opt_scalar_int_mode mode_iter;
    3726         2750 :       if (padding_correction == 0 && !STRICT_ALIGNMENT)
    3727              :         {
    3728         7488 :           FOR_EACH_MODE_FROM (mode_iter, min_mode)
    3729              :             {
    3730         7488 :               unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
    3731         7488 :               if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
    3732         4741 :                   && msize <= BITS_PER_WORD)
    3733         4738 :                 bitsize = msize;
    3734              :               else
    3735              :                 break;
    3736              :             }
    3737              :         }
    3738              : 
    3739              :       /* We need a new source operand each time bitpos is on a word
    3740              :          boundary.  */
    3741         2750 :       if (bitpos % BITS_PER_WORD == 0)
    3742         1227 :         src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
    3743              : 
    3744              :       /* Use bitpos for the source extraction (left justified) and
    3745              :          xbitpos for the destination store (right justified).  */
    3746         5500 :       store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
    3747              :                        0, 0, word_mode,
    3748         2750 :                        extract_bit_field (src_word, bitsize,
    3749         2750 :                                           bitpos % BITS_PER_WORD, 1,
    3750              :                                           NULL_RTX, word_mode, word_mode,
    3751              :                                           false, NULL),
    3752              :                        false, false);
    3753              :     }
    3754              : 
    3755         1224 :   if (mode == BLKmode)
    3756              :     {
    3757              :       /* Find the smallest integer mode large enough to hold the
    3758              :          entire structure.  */
    3759            0 :       opt_scalar_int_mode mode_iter;
    3760            0 :       FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    3761            0 :         if (GET_MODE_SIZE (mode_iter.require ()) >= bytes)
    3762              :           break;
    3763              : 
    3764              :       /* A suitable mode should have been found.  */
    3765            0 :       mode = mode_iter.require ();
    3766              :     }
    3767              : 
    3768         3672 :   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
    3769              :     dst_mode = word_mode;
    3770              :   else
    3771          498 :     dst_mode = mode;
    3772         1224 :   dst = gen_reg_rtx (dst_mode);
    3773              : 
    3774         3675 :   for (i = 0; i < n_regs; i++)
    3775         1227 :     emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
    3776              : 
    3777         1224 :   if (mode != dst_mode)
    3778          726 :     dst = gen_lowpart (mode, dst);
    3779              : 
    3780              :   return dst;
    3781              : }
    3782              : 
    3783              : /* Add a USE expression for REG to the (possibly empty) list pointed
    3784              :    to by CALL_FUSAGE.  REG must denote a hard register.  */
    3785              : 
    3786              : void
    3787     11637708 : use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
    3788              : {
    3789     11637708 :   gcc_assert (REG_P (reg));
    3790              : 
    3791     11637708 :   if (!HARD_REGISTER_P (reg))
    3792              :     return;
    3793              : 
    3794     11637708 :   *call_fusage
    3795     11637708 :     = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
    3796              : }
    3797              : 
    3798              : /* Add a CLOBBER expression for REG to the (possibly empty) list pointed
    3799              :    to by CALL_FUSAGE.  REG must denote a hard register.  */
    3800              : 
    3801              : void
    3802            0 : clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
    3803              : {
    3804            0 :   gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
    3805              : 
    3806            0 :   *call_fusage
    3807            0 :     = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
    3808            0 : }
    3809              : 
    3810              : /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
    3811              :    starting at REGNO.  All of these registers must be hard registers.  */
    3812              : 
    3813              : void
    3814         1608 : use_regs (rtx *call_fusage, int regno, int nregs)
    3815              : {
    3816         1608 :   int i;
    3817              : 
    3818         1608 :   gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
    3819              : 
    3820         3224 :   for (i = 0; i < nregs; i++)
    3821         1616 :     use_reg (call_fusage, regno_reg_rtx[regno + i]);
    3822         1608 : }
    3823              : 
    3824              : /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
    3825              :    PARALLEL REGS.  This is for calls that pass values in multiple
    3826              :    non-contiguous locations.  The Irix 6 ABI has examples of this.  */
    3827              : 
    3828              : void
    3829       293930 : use_group_regs (rtx *call_fusage, rtx regs)
    3830              : {
    3831       293930 :   int i;
    3832              : 
    3833       872505 :   for (i = 0; i < XVECLEN (regs, 0); i++)
    3834              :     {
    3835       578575 :       rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
    3836              : 
    3837              :       /* A NULL entry means the parameter goes both on the stack and in
    3838              :          registers.  This can also be a MEM for targets that pass values
    3839              :          partially on the stack and partially in registers.  */
    3840       578575 :       if (reg != 0 && REG_P (reg))
    3841       578575 :         use_reg (call_fusage, reg);
    3842              :     }
    3843       293930 : }
    3844              : 
    3845              : /* Return the defining gimple statement for SSA_NAME NAME if it is an
    3846              :    assignment and the code of the expression on the RHS is CODE.  Return
    3847              :    NULL otherwise.  */
    3848              : 
    3849              : static gimple *
    3850     12104560 : get_def_for_expr (tree name, enum tree_code code)
    3851              : {
    3852     12104560 :   gimple *def_stmt;
    3853              : 
    3854     12104560 :   if (TREE_CODE (name) != SSA_NAME)
    3855              :     return NULL;
    3856              : 
    3857      9427804 :   def_stmt = get_gimple_for_ssa_name (name);
    3858      9427804 :   if (!def_stmt
    3859      2028046 :       || !is_gimple_assign (def_stmt)
    3860     11454360 :       || gimple_assign_rhs_code (def_stmt) != code)
    3861      9395395 :     return NULL;
    3862              : 
    3863              :   return def_stmt;
    3864              : }
    3865              : 
    3866              : /* Return the defining gimple statement for SSA_NAME NAME if it is an
    3867              :    assignment and the class of the expression on the RHS is CLASS.  Return
    3868              :    NULL otherwise.  */
    3869              : 
    3870              : static gimple *
    3871        16988 : get_def_for_expr_class (tree name, enum tree_code_class tclass)
    3872              : {
    3873        16988 :   gimple *def_stmt;
    3874              : 
    3875        16988 :   if (TREE_CODE (name) != SSA_NAME)
    3876              :     return NULL;
    3877              : 
    3878        16988 :   def_stmt = get_gimple_for_ssa_name (name);
    3879        16988 :   if (!def_stmt
    3880        14871 :       || !is_gimple_assign (def_stmt)
    3881        31859 :       || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
    3882         2250 :     return NULL;
    3883              : 
    3884              :   return def_stmt;
    3885              : }
    3886              : 
    3887              : /* Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
    3888              :    its length in bytes.  */
    3889              : 
    3890              : rtx
    3891       158956 : clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
    3892              :                      unsigned int expected_align, HOST_WIDE_INT expected_size,
    3893              :                      unsigned HOST_WIDE_INT min_size,
    3894              :                      unsigned HOST_WIDE_INT max_size,
    3895              :                      unsigned HOST_WIDE_INT probable_max_size,
    3896              :                      unsigned ctz_size)
    3897              : {
    3898       158956 :   machine_mode mode = GET_MODE (object);
    3899       158956 :   unsigned int align;
    3900              : 
    3901       158956 :   gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
    3902              : 
    3903              :   /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
    3904              :      just move a zero.  Otherwise, do this a piece at a time.  */
    3905       158956 :   poly_int64 size_val;
    3906       158956 :   if (mode != BLKmode
    3907        58635 :       && poly_int_rtx_p (size, &size_val)
    3908       217591 :       && known_eq (size_val, GET_MODE_SIZE (mode)))
    3909              :     {
    3910        58635 :       rtx zero = CONST0_RTX (mode);
    3911        58635 :       if (zero != NULL)
    3912              :         {
    3913        58635 :           emit_move_insn (object, zero);
    3914        58635 :           return NULL;
    3915              :         }
    3916              : 
    3917            0 :       if (COMPLEX_MODE_P (mode))
    3918              :         {
    3919            0 :           zero = CONST0_RTX (GET_MODE_INNER (mode));
    3920            0 :           if (zero != NULL)
    3921              :             {
    3922            0 :               write_complex_part (object, zero, 0, true);
    3923            0 :               write_complex_part (object, zero, 1, false);
    3924            0 :               return NULL;
    3925              :             }
    3926              :         }
    3927              :     }
    3928              : 
    3929       100321 :   if (size == const0_rtx)
    3930              :     return NULL;
    3931              : 
    3932       100320 :   align = MEM_ALIGN (object);
    3933              : 
    3934       100320 :   if (CONST_INT_P (size)
    3935       100320 :       && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
    3936              :                                                  CLEAR_BY_PIECES,
    3937              :                                                  optimize_insn_for_speed_p ()))
    3938        72001 :     clear_by_pieces (object, INTVAL (size), align);
    3939        28319 :   else if (set_storage_via_setmem (object, size, const0_rtx, align,
    3940              :                                    expected_align, expected_size,
    3941              :                                    min_size, max_size, probable_max_size))
    3942              :     ;
    3943        16140 :   else if (try_store_by_multiple_pieces (object, size, ctz_size,
    3944              :                                          min_size, max_size,
    3945              :                                          NULL_RTX, 0, align))
    3946              :     ;
    3947        15876 :   else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
    3948        15876 :     return set_storage_via_libcall (object, size, const0_rtx,
    3949        15876 :                                     method == BLOCK_OP_TAILCALL);
    3950              :   else
    3951            0 :     gcc_unreachable ();
    3952              : 
    3953              :   return NULL;
    3954              : }
    3955              : 
    3956              : rtx
    3957       111530 : clear_storage (rtx object, rtx size, enum block_op_methods method)
    3958              : {
    3959       111530 :   unsigned HOST_WIDE_INT max, min = 0;
    3960       111530 :   if (GET_CODE (size) == CONST_INT)
    3961       111530 :     min = max = UINTVAL (size);
    3962              :   else
    3963            0 :     max = GET_MODE_MASK (GET_MODE (size));
    3964       111530 :   return clear_storage_hints (object, size, method, 0, -1, min, max, max, 0);
    3965              : }
    3966              : 
    3967              : 
    3968              : /* A subroutine of clear_storage.  Expand a call to memset.
    3969              :    Return the return value of memset, 0 otherwise.  */
    3970              : 
    3971              : rtx
    3972        15877 : set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
    3973              : {
    3974        15877 :   tree call_expr, fn, object_tree, size_tree, val_tree;
    3975        15877 :   machine_mode size_mode;
    3976              : 
    3977        15877 :   object = copy_addr_to_reg (XEXP (object, 0));
    3978        15877 :   object_tree = make_tree (ptr_type_node, object);
    3979              : 
    3980        15877 :   if (!CONST_INT_P (val))
    3981            0 :     val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
    3982        15877 :   val_tree = make_tree (integer_type_node, val);
    3983              : 
    3984        15877 :   size_mode = TYPE_MODE (sizetype);
    3985        15877 :   size = convert_to_mode (size_mode, size, 1);
    3986        15877 :   size = copy_to_mode_reg (size_mode, size);
    3987        15877 :   size_tree = make_tree (sizetype, size);
    3988              : 
    3989              :   /* It is incorrect to use the libcall calling conventions for calls to
    3990              :      memset because it can be provided by the user.  */
    3991        15877 :   fn = builtin_decl_implicit (BUILT_IN_MEMSET);
    3992        15877 :   call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
    3993        15877 :   CALL_EXPR_TAILCALL (call_expr) = tailcall;
    3994              : 
    3995        15877 :   return expand_call (call_expr, NULL_RTX, false);
    3996              : }
    3997              : 
    3998              : /* Expand a setmem pattern; return true if successful.  */
    3999              : 
    4000              : bool
    4001        36998 : set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
    4002              :                         unsigned int expected_align, HOST_WIDE_INT expected_size,
    4003              :                         unsigned HOST_WIDE_INT min_size,
    4004              :                         unsigned HOST_WIDE_INT max_size,
    4005              :                         unsigned HOST_WIDE_INT probable_max_size)
    4006              : {
    4007              :   /* Try the most limited insn first, because there's no point
    4008              :      including more than one in the machine description unless
    4009              :      the more limited one has some advantage.  */
    4010              : 
    4011        36998 :   if (expected_align < align)
    4012              :     expected_align = align;
    4013        36998 :   if (expected_size != -1)
    4014              :     {
    4015            8 :       if ((unsigned HOST_WIDE_INT)expected_size > max_size)
    4016            0 :         expected_size = max_size;
    4017            8 :       if ((unsigned HOST_WIDE_INT)expected_size < min_size)
    4018            0 :         expected_size = min_size;
    4019              :     }
    4020              : 
    4021        36998 :   opt_scalar_int_mode mode_iter;
    4022       224452 :   FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    4023              :     {
    4024       201910 :       scalar_int_mode mode = mode_iter.require ();
    4025       201910 :       enum insn_code code = direct_optab_handler (setmem_optab, mode);
    4026              : 
    4027       201910 :       if (code != CODE_FOR_nothing
    4028              :           /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
    4029              :              here because if SIZE is less than the mode mask, as it is
    4030              :              returned by the macro, it will definitely be less than the
    4031              :              actual mode mask.  Since SIZE is within the Pmode address
    4032              :              space, we limit MODE to Pmode.  */
    4033       201910 :           && ((CONST_INT_P (size)
    4034        31815 :                && ((unsigned HOST_WIDE_INT) INTVAL (size)
    4035        31815 :                    <= (GET_MODE_MASK (mode) >> 1)))
    4036        26843 :               || max_size <= (GET_MODE_MASK (mode) >> 1)
    4037        32148 :               || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
    4038              :         {
    4039        47928 :           class expand_operand ops[9];
    4040        47928 :           unsigned int nops;
    4041              : 
    4042        47928 :           nops = insn_data[(int) code].n_generator_args;
    4043        47928 :           gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
    4044              : 
    4045        47928 :           create_fixed_operand (&ops[0], object);
    4046              :           /* The check above guarantees that this size conversion is valid.  */
    4047        47928 :           create_convert_operand_to (&ops[1], size, mode, true);
    4048        47928 :           create_convert_operand_from (&ops[2], val, byte_mode, true);
    4049        47928 :           create_integer_operand (&ops[3], align / BITS_PER_UNIT);
    4050        47928 :           if (nops >= 6)
    4051              :             {
    4052        47928 :               create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
    4053        47928 :               create_integer_operand (&ops[5], expected_size);
    4054              :             }
    4055        47928 :           if (nops >= 8)
    4056              :             {
    4057        47928 :               create_integer_operand (&ops[6], min_size);
    4058              :               /* If we cannot represent the maximal size,
    4059              :                  make parameter NULL.  */
    4060        47928 :               if ((HOST_WIDE_INT) max_size != -1)
    4061        44634 :                 create_integer_operand (&ops[7], max_size);
    4062              :               else
    4063         3294 :                 create_fixed_operand (&ops[7], NULL);
    4064              :             }
    4065        47928 :           if (nops == 9)
    4066              :             {
    4067              :               /* If we cannot represent the maximal size,
    4068              :                  make parameter NULL.  */
    4069        47928 :               if ((HOST_WIDE_INT) probable_max_size != -1)
    4070        44790 :                 create_integer_operand (&ops[8], probable_max_size);
    4071              :               else
    4072         3138 :                 create_fixed_operand (&ops[8], NULL);
    4073              :             }
    4074        47928 :           gcc_assert (min_size != max_size
    4075              :                       || rtx_equal_p (ops[1].value, GEN_INT (min_size)));
    4076        47928 :           if (maybe_expand_insn (code, nops, ops))
    4077        14456 :             return true;
    4078              :         }
    4079              :     }
    4080              : 
    4081              :   return false;
    4082              : }
    4083              : 
    4084              : 
    4085              : /* Write to one of the components of the complex value CPLX.  Write VAL to
    4086              :    the real part if IMAG_P is false, and the imaginary part if its true.
    4087              :    If UNDEFINED_P then the value in CPLX is currently undefined.  */
    4088              : 
    4089              : void
    4090       575480 : write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
    4091              : {
    4092       575480 :   machine_mode cmode;
    4093       575480 :   scalar_mode imode;
    4094       575480 :   unsigned ibitsize;
    4095              : 
    4096       575480 :   if (GET_CODE (cplx) == CONCAT)
    4097              :     {
    4098       517036 :       emit_move_insn (XEXP (cplx, imag_p), val);
    4099       517036 :       return;
    4100              :     }
    4101              : 
    4102        58444 :   cmode = GET_MODE (cplx);
    4103        58444 :   imode = GET_MODE_INNER (cmode);
    4104        58444 :   ibitsize = GET_MODE_BITSIZE (imode);
    4105              : 
    4106              :   /* For MEMs simplify_gen_subreg may generate an invalid new address
    4107              :      because, e.g., the original address is considered mode-dependent
    4108              :      by the target, which restricts simplify_subreg from invoking
    4109              :      adjust_address_nv.  Instead of preparing fallback support for an
    4110              :      invalid address, we call adjust_address_nv directly.  */
    4111        58444 :   if (MEM_P (cplx))
    4112              :     {
    4113        69087 :       emit_move_insn (adjust_address_nv (cplx, imode,
    4114              :                                          imag_p ? GET_MODE_SIZE (imode) : 0),
    4115              :                       val);
    4116        46058 :       return;
    4117              :     }
    4118              : 
    4119              :   /* If the sub-object is at least word sized, then we know that subregging
    4120              :      will work.  This special case is important, since store_bit_field
    4121              :      wants to operate on integer modes, and there's rarely an OImode to
    4122              :      correspond to TCmode.  */
    4123        12386 :   if (ibitsize >= BITS_PER_WORD
    4124              :       /* For hard regs we have exact predicates.  Assume we can split
    4125              :          the original object if it spans an even number of hard regs.
    4126              :          This special case is important for SCmode on 64-bit platforms
    4127              :          where the natural size of floating-point regs is 32-bit.  */
    4128        12386 :       || (REG_P (cplx)
    4129         7324 :           && REGNO (cplx) < FIRST_PSEUDO_REGISTER
    4130         7122 :           && REG_NREGS (cplx) % 2 == 0))
    4131              :     {
    4132         5078 :       rtx part = simplify_gen_subreg (imode, cplx, cmode,
    4133         7617 :                                       imag_p ? GET_MODE_SIZE (imode) : 0);
    4134         5078 :       if (part)
    4135              :         {
    4136         5078 :           emit_move_insn (part, val);
    4137         5078 :           return;
    4138              :         }
    4139              :       else
    4140              :         /* simplify_gen_subreg may fail for sub-word MEMs.  */
    4141            0 :         gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
    4142              :     }
    4143              : 
    4144        10962 :   store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
    4145              :                    false, undefined_p);
    4146              : }
    4147              : 
    4148              : /* Extract one of the components of the complex value CPLX.  Extract the
    4149              :    real part if IMAG_P is false, and the imaginary part if it's true.  */
    4150              : 
    4151              : rtx
    4152       562965 : read_complex_part (rtx cplx, bool imag_p)
    4153              : {
    4154       562965 :   machine_mode cmode;
    4155       562965 :   scalar_mode imode;
    4156       562965 :   unsigned ibitsize;
    4157              : 
    4158       562965 :   if (GET_CODE (cplx) == CONCAT)
    4159       348179 :     return XEXP (cplx, imag_p);
    4160              : 
    4161       214786 :   cmode = GET_MODE (cplx);
    4162       214786 :   imode = GET_MODE_INNER (cmode);
    4163       214786 :   ibitsize = GET_MODE_BITSIZE (imode);
    4164              : 
    4165              :   /* Special case reads from complex constants that got spilled to memory.  */
    4166       214786 :   if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
    4167              :     {
    4168        37931 :       tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
    4169        37931 :       if (decl && TREE_CODE (decl) == COMPLEX_CST)
    4170              :         {
    4171            0 :           tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
    4172            0 :           if (CONSTANT_CLASS_P (part))
    4173            0 :             return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
    4174              :         }
    4175              :     }
    4176              : 
    4177              :   /* For MEMs simplify_gen_subreg may generate an invalid new address
    4178              :      because, e.g., the original address is considered mode-dependent
    4179              :      by the target, which restricts simplify_subreg from invoking
    4180              :      adjust_address_nv.  Instead of preparing fallback support for an
    4181              :      invalid address, we call adjust_address_nv directly.  */
    4182       214786 :   if (MEM_P (cplx))
    4183       237322 :     return adjust_address_nv (cplx, imode,
    4184              :                               imag_p ? GET_MODE_SIZE (imode) : 0);
    4185              : 
    4186              :   /* If the sub-object is at least word sized, then we know that subregging
    4187              :      will work.  This special case is important, since extract_bit_field
    4188              :      wants to operate on integer modes, and there's rarely an OImode to
    4189              :      correspond to TCmode.  */
    4190        56398 :   if (ibitsize >= BITS_PER_WORD
    4191              :       /* For hard regs we have exact predicates.  Assume we can split
    4192              :          the original object if it spans an even number of hard regs.
    4193              :          This special case is important for SCmode on 64-bit platforms
    4194              :          where the natural size of floating-point regs is 32-bit.  */
    4195        56398 :       || (REG_P (cplx)
    4196        35442 :           && REGNO (cplx) < FIRST_PSEUDO_REGISTER
    4197          292 :           && REG_NREGS (cplx) % 2 == 0))
    4198              :     {
    4199        10297 :       rtx ret = simplify_gen_subreg (imode, cplx, cmode,
    4200        15445 :                                      imag_p ? GET_MODE_SIZE (imode) : 0);
    4201        10297 :       if (ret)
    4202              :         return ret;
    4203              :     }
    4204              : 
    4205        69149 :   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
    4206              :                             true, NULL_RTX, imode, imode, false, NULL);
    4207              : }
    4208              : 
    4209              : /* A subroutine of emit_move_insn_1.  Yet another lowpart generator.
    4210              :    NEW_MODE and OLD_MODE are the same size.  Return NULL if X cannot be
    4211              :    represented in NEW_MODE.  If FORCE is true, this will never happen, as
    4212              :    we'll force-create a SUBREG if needed.  */
    4213              : 
    4214              : static rtx
    4215       277087 : emit_move_change_mode (machine_mode new_mode,
    4216              :                        machine_mode old_mode, rtx x, bool force)
    4217              : {
    4218       277087 :   rtx ret;
    4219              : 
    4220       277087 :   if (push_operand (x, GET_MODE (x)))
    4221              :     {
    4222         1318 :       ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
    4223         1318 :       MEM_COPY_ATTRIBUTES (ret, x);
    4224              :     }
    4225       275769 :   else if (MEM_P (x))
    4226              :     {
    4227              :       /* We don't have to worry about changing the address since the
    4228              :          size in bytes is supposed to be the same.  */
    4229        52567 :       if (reload_in_progress)
    4230              :         {
    4231              :           /* Copy the MEM to change the mode and move any
    4232              :              substitutions from the old MEM to the new one.  */
    4233            0 :           ret = adjust_address_nv (x, new_mode, 0);
    4234            0 :           copy_replacements (x, ret);
    4235              :         }
    4236              :       else
    4237        52567 :         ret = adjust_address (x, new_mode, 0);
    4238              :     }
    4239              :   else
    4240              :     {
    4241              :       /* Note that we do want simplify_subreg's behavior of validating
    4242              :          that the new mode is ok for a hard register.  If we were to use
    4243              :          simplify_gen_subreg, we would create the subreg, but would
    4244              :          probably run into the target not being able to implement it.  */
    4245              :       /* Except, of course, when FORCE is true, when this is exactly what
    4246              :          we want.  Which is needed for CCmodes on some targets.  */
    4247       223202 :       if (force)
    4248       223201 :         ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
    4249              :       else
    4250            1 :         ret = simplify_subreg (new_mode, x, old_mode, 0);
    4251              :     }
    4252              : 
    4253       277087 :   return ret;
    4254              : }
    4255              : 
    4256              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X using
    4257              :    an integer mode of the same size as MODE.  Returns the instruction
    4258              :    emitted, or NULL if such a move could not be generated.  */
    4259              : 
    4260              : static rtx_insn *
    4261       138544 : emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
    4262              : {
    4263       138544 :   scalar_int_mode imode;
    4264       138544 :   enum insn_code code;
    4265              : 
    4266              :   /* There must exist a mode of the exact size we require.  */
    4267       138544 :   if (!int_mode_for_mode (mode).exists (&imode))
    4268            0 :     return NULL;
    4269              : 
    4270              :   /* The target must support moves in this mode.  */
    4271       138544 :   code = optab_handler (mov_optab, imode);
    4272       138544 :   if (code == CODE_FOR_nothing)
    4273              :     return NULL;
    4274              : 
    4275       138544 :   x = emit_move_change_mode (imode, mode, x, force);
    4276       138544 :   if (x == NULL_RTX)
    4277              :     return NULL;
    4278       138543 :   y = emit_move_change_mode (imode, mode, y, force);
    4279       138543 :   if (y == NULL_RTX)
    4280              :     return NULL;
    4281       138543 :   return emit_insn (GEN_FCN (code) (x, y));
    4282              : }
    4283              : 
    4284              : /* A subroutine of emit_move_insn_1.  X is a push_operand in MODE.
    4285              :    Return an equivalent MEM that does not use an auto-increment.  */
    4286              : 
    4287              : rtx
    4288         3637 : emit_move_resolve_push (machine_mode mode, rtx x)
    4289              : {
    4290         3637 :   enum rtx_code code = GET_CODE (XEXP (x, 0));
    4291         3637 :   rtx temp;
    4292              : 
    4293         7274 :   poly_int64 adjust = GET_MODE_SIZE (mode);
    4294              : #ifdef PUSH_ROUNDING
    4295         3637 :   adjust = PUSH_ROUNDING (adjust);
    4296              : #endif
    4297         3637 :   if (code == PRE_DEC || code == POST_DEC)
    4298         3241 :     adjust = -adjust;
    4299          396 :   else if (code == PRE_MODIFY || code == POST_MODIFY)
    4300              :     {
    4301          396 :       rtx expr = XEXP (XEXP (x, 0), 1);
    4302              : 
    4303          396 :       gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
    4304          396 :       poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
    4305          396 :       if (GET_CODE (expr) == MINUS)
    4306            0 :         val = -val;
    4307          396 :       gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
    4308              :       adjust = val;
    4309              :     }
    4310              : 
    4311              :   /* Do not use anti_adjust_stack, since we don't want to update
    4312              :      stack_pointer_delta.  */
    4313         3641 :   temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
    4314         3637 :                               gen_int_mode (adjust, Pmode), stack_pointer_rtx,
    4315              :                               0, OPTAB_LIB_WIDEN);
    4316         3637 :   if (temp != stack_pointer_rtx)
    4317            0 :     emit_move_insn (stack_pointer_rtx, temp);
    4318              : 
    4319         3637 :   switch (code)
    4320              :     {
    4321         3637 :     case PRE_INC:
    4322         3637 :     case PRE_DEC:
    4323         3637 :     case PRE_MODIFY:
    4324         3637 :       temp = stack_pointer_rtx;
    4325         3637 :       break;
    4326              :     case POST_INC:
    4327              :     case POST_DEC:
    4328              :     case POST_MODIFY:
    4329            0 :       temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
    4330            0 :       break;
    4331            0 :     default:
    4332            0 :       gcc_unreachable ();
    4333              :     }
    4334              : 
    4335         3637 :   return replace_equiv_address (x, temp);
    4336              : }
    4337              : 
    4338              : /* A subroutine of emit_move_complex.  Generate a move from Y into X.
    4339              :    X is known to satisfy push_operand, and MODE is known to be complex.
    4340              :    Returns the last instruction emitted.  */
    4341              : 
    4342              : rtx_insn *
    4343         5646 : emit_move_complex_push (machine_mode mode, rtx x, rtx y)
    4344              : {
    4345         5646 :   scalar_mode submode = GET_MODE_INNER (mode);
    4346         5646 :   bool imag_first;
    4347              : 
    4348              : #ifdef PUSH_ROUNDING
    4349        11292 :   poly_int64 submodesize = GET_MODE_SIZE (submode);
    4350              : 
    4351              :   /* In case we output to the stack, but the size is smaller than the
    4352              :      machine can push exactly, we need to use move instructions.  */
    4353         5646 :   if (maybe_ne (PUSH_ROUNDING (submodesize), submodesize))
    4354              :     {
    4355          718 :       x = emit_move_resolve_push (mode, x);
    4356          718 :       return emit_move_insn (x, y);
    4357              :     }
    4358              : #endif
    4359              : 
    4360              :   /* Note that the real part always precedes the imag part in memory
    4361              :      regardless of machine's endianness.  */
    4362         4928 :   switch (GET_CODE (XEXP (x, 0)))
    4363              :     {
    4364              :     case PRE_DEC:
    4365              :     case POST_DEC:
    4366              :       imag_first = true;
    4367              :       break;
    4368            0 :     case PRE_INC:
    4369            0 :     case POST_INC:
    4370            0 :       imag_first = false;
    4371            0 :       break;
    4372            0 :     default:
    4373            0 :       gcc_unreachable ();
    4374              :     }
    4375              : 
    4376         4928 :   emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
    4377              :                   read_complex_part (y, imag_first));
    4378         4928 :   return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
    4379         4928 :                          read_complex_part (y, !imag_first));
    4380              : }
    4381              : 
    4382              : /* A subroutine of emit_move_complex.  Perform the move from Y to X
    4383              :    via two moves of the parts.  Returns the last instruction emitted.  */
    4384              : 
    4385              : rtx_insn *
    4386        88868 : emit_move_complex_parts (rtx x, rtx y)
    4387              : {
    4388              :   /* Show the output dies here.  This is necessary for SUBREGs
    4389              :      of pseudos since we cannot track their lifetimes correctly;
    4390              :      hard regs shouldn't appear here except as return values.  */
    4391        88868 :   if (!reload_completed && !reload_in_progress
    4392       177736 :       && REG_P (x) && !reg_overlap_mentioned_p (x, y))
    4393         6186 :     emit_clobber (x);
    4394              : 
    4395        88868 :   write_complex_part (x, read_complex_part (y, false), false, true);
    4396        88868 :   write_complex_part (x, read_complex_part (y, true), true, false);
    4397              : 
    4398        88868 :   return get_last_insn ();
    4399              : }
    4400              : 
    4401              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4402              :    MODE is known to be complex.  Returns the last instruction emitted.  */
    4403              : 
    4404              : static rtx_insn *
    4405       111410 : emit_move_complex (machine_mode mode, rtx x, rtx y)
    4406              : {
    4407       111410 :   bool try_int;
    4408              : 
    4409              :   /* Need to take special care for pushes, to maintain proper ordering
    4410              :      of the data, and possibly extra padding.  */
    4411       111410 :   if (push_operand (x, mode))
    4412         5038 :     return emit_move_complex_push (mode, x, y);
    4413              : 
    4414              :   /* See if we can coerce the target into moving both values at once, except
    4415              :      for floating point where we favor moving as parts if this is easy.  */
    4416       106372 :   if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
    4417        63029 :       && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
    4418        63029 :       && !(REG_P (x)
    4419         2263 :            && HARD_REGISTER_P (x)
    4420          597 :            && REG_NREGS (x) == 1)
    4421       169401 :       && !(REG_P (y)
    4422         3336 :            && HARD_REGISTER_P (y)
    4423         1668 :            && REG_NREGS (y) == 1))
    4424              :     try_int = false;
    4425              :   /* Not possible if the values are inherently not adjacent.  */
    4426        43343 :   else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
    4427              :     try_int = false;
    4428              :   /* Is possible if both are registers (or subregs of registers).  */
    4429        18317 :   else if (register_operand (x, mode) && register_operand (y, mode))
    4430              :     try_int = true;
    4431              :   /* If one of the operands is a memory, and alignment constraints
    4432              :      are friendly enough, we may be able to do combined memory operations.
    4433              :      We do not attempt this if Y is a constant because that combination is
    4434              :      usually better with the by-parts thing below.  */
    4435          635 :   else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
    4436              :            && (!STRICT_ALIGNMENT
    4437              :                || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
    4438              :     try_int = true;
    4439              :   else
    4440              :     try_int = false;
    4441              : 
    4442              :   if (try_int)
    4443              :     {
    4444        18317 :       rtx_insn *ret;
    4445              : 
    4446              :       /* For memory to memory moves, optimal behavior can be had with the
    4447              :          existing block move logic.  But use normal expansion if optimizing
    4448              :          for size.  */
    4449        18317 :       if (MEM_P (x) && MEM_P (y))
    4450              :         {
    4451          726 :           emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
    4452          360 :                            (optimize_insn_for_speed_p()
    4453              :                             ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
    4454          360 :           return get_last_insn ();
    4455              :         }
    4456              : 
    4457        17957 :       ret = emit_move_via_integer (mode, x, y, true);
    4458        17957 :       if (ret)
    4459              :         return ret;
    4460              :     }
    4461              : 
    4462        88055 :   return emit_move_complex_parts (x, y);
    4463              : }
    4464              : 
    4465              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4466              :    MODE is known to be MODE_CC.  Returns the last instruction emitted.  */
    4467              : 
    4468              : static rtx_insn *
    4469            0 : emit_move_ccmode (machine_mode mode, rtx x, rtx y)
    4470              : {
    4471            0 :   rtx_insn *ret;
    4472              : 
    4473              :   /* Assume all MODE_CC modes are equivalent; if we have movcc, use it.  */
    4474            0 :   if (mode != CCmode)
    4475              :     {
    4476            0 :       enum insn_code code = optab_handler (mov_optab, CCmode);
    4477            0 :       if (code != CODE_FOR_nothing)
    4478              :         {
    4479            0 :           x = emit_move_change_mode (CCmode, mode, x, true);
    4480            0 :           y = emit_move_change_mode (CCmode, mode, y, true);
    4481            0 :           return emit_insn (GEN_FCN (code) (x, y));
    4482              :         }
    4483              :     }
    4484              : 
    4485              :   /* Otherwise, find the MODE_INT mode of the same width.  */
    4486            0 :   ret = emit_move_via_integer (mode, x, y, false);
    4487            0 :   gcc_assert (ret != NULL);
    4488              :   return ret;
    4489              : }
    4490              : 
    4491              : /* Return true if word I of OP lies entirely in the
    4492              :    undefined bits of a paradoxical subreg.  */
    4493              : 
    4494              : static bool
    4495            2 : undefined_operand_subword_p (const_rtx op, int i)
    4496              : {
    4497            2 :   if (GET_CODE (op) != SUBREG)
    4498              :     return false;
    4499            0 :   machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    4500            0 :   poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
    4501            0 :   return (known_ge (offset, GET_MODE_SIZE (innermostmode))
    4502            0 :           || known_le (offset, -UNITS_PER_WORD));
    4503              : }
    4504              : 
    4505              : /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    4506              :    MODE is any multi-word or full-word mode that lacks a move_insn
    4507              :    pattern.  Note that you will get better code if you define such
    4508              :    patterns, even if they must turn into multiple assembler instructions.  */
    4509              : 
    4510              : static rtx_insn *
    4511            1 : emit_move_multi_word (machine_mode mode, rtx x, rtx y)
    4512              : {
    4513            1 :   rtx_insn *last_insn = 0;
    4514            1 :   rtx_insn *seq;
    4515            1 :   rtx inner;
    4516            1 :   bool need_clobber;
    4517            1 :   int i, mode_size;
    4518              : 
    4519              :   /* This function can only handle cases where the number of words is
    4520              :      known at compile time.  */
    4521            1 :   mode_size = GET_MODE_SIZE (mode).to_constant ();
    4522            1 :   gcc_assert (mode_size >= UNITS_PER_WORD);
    4523              : 
    4524              :   /* If X is a push on the stack, do the push now and replace
    4525              :      X with a reference to the stack pointer.  */
    4526            1 :   if (push_operand (x, mode))
    4527            0 :     x = emit_move_resolve_push (mode, x);
    4528              : 
    4529              :   /* If we are in reload, see if either operand is a MEM whose address
    4530              :      is scheduled for replacement.  */
    4531            0 :   if (reload_in_progress && MEM_P (x)
    4532            1 :       && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
    4533            0 :     x = replace_equiv_address_nv (x, inner);
    4534            0 :   if (reload_in_progress && MEM_P (y)
    4535            1 :       && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
    4536            0 :     y = replace_equiv_address_nv (y, inner);
    4537              : 
    4538            1 :   start_sequence ();
    4539              : 
    4540            1 :   need_clobber = false;
    4541            3 :   for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
    4542              :     {
    4543              :       /* Do not generate code for a move if it would go entirely
    4544              :          to the non-existing bits of a paradoxical subreg.  */
    4545            1 :       if (undefined_operand_subword_p (x, i))
    4546            0 :         continue;
    4547              : 
    4548            1 :       rtx xpart = operand_subword (x, i, 1, mode);
    4549            1 :       rtx ypart;
    4550              : 
    4551              :       /* Do not generate code for a move if it would come entirely
    4552              :          from the undefined bits of a paradoxical subreg.  */
    4553            1 :       if (undefined_operand_subword_p (y, i))
    4554            0 :         continue;
    4555              : 
    4556            1 :       ypart = operand_subword (y, i, 1, mode);
    4557              : 
    4558              :       /* If we can't get a part of Y, put Y into memory if it is a
    4559              :          constant.  Otherwise, force it into a register.  Then we must
    4560              :          be able to get a part of Y.  */
    4561            1 :       if (ypart == 0 && CONSTANT_P (y))
    4562              :         {
    4563            0 :           y = use_anchored_address (force_const_mem (mode, y));
    4564            0 :           ypart = operand_subword (y, i, 1, mode);
    4565              :         }
    4566            0 :       else if (ypart == 0)
    4567            0 :         ypart = operand_subword_force (y, i, mode);
    4568              : 
    4569            1 :       gcc_assert (xpart && ypart);
    4570              : 
    4571            1 :       need_clobber |= (GET_CODE (xpart) == SUBREG);
    4572              : 
    4573            1 :       last_insn = emit_move_insn (xpart, ypart);
    4574              :     }
    4575              : 
    4576            1 :   seq = end_sequence ();
    4577              : 
    4578              :   /* Show the output dies here.  This is necessary for SUBREGs
    4579              :      of pseudos since we cannot track their lifetimes correctly;
    4580              :      hard regs shouldn't appear here except as return values.
    4581              :      We never want to emit such a clobber after reload.  */
    4582            1 :   if (x != y
    4583            1 :       && ! (reload_in_progress || reload_completed)
    4584            1 :       && need_clobber != 0)
    4585            1 :     emit_clobber (x);
    4586              : 
    4587            1 :   emit_insn (seq);
    4588              : 
    4589            1 :   return last_insn;
    4590              : }
    4591              : 
    4592              : /* Low level part of emit_move_insn.
    4593              :    Called just like emit_move_insn, but assumes X and Y
    4594              :    are basically valid.  */
    4595              : 
    4596              : rtx_insn *
    4597     77762177 : emit_move_insn_1 (rtx x, rtx y)
    4598              : {
    4599     77762177 :   machine_mode mode = GET_MODE (x);
    4600     77762177 :   enum insn_code code;
    4601              : 
    4602     77762177 :   gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
    4603              : 
    4604     77762177 :   code = optab_handler (mov_optab, mode);
    4605     77762177 :   if (code != CODE_FOR_nothing)
    4606     77530180 :     return emit_insn (GEN_FCN (code) (x, y));
    4607              : 
    4608              :   /* Expand complex moves by moving real part and imag part.  */
    4609       231997 :   if (COMPLEX_MODE_P (mode))
    4610       111410 :     return emit_move_complex (mode, x, y);
    4611              : 
    4612              :   if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
    4613              :       || ALL_FIXED_POINT_MODE_P (mode))
    4614              :     {
    4615       120586 :       rtx_insn *result = emit_move_via_integer (mode, x, y, true);
    4616              : 
    4617              :       /* If we can't find an integer mode, use multi words.  */
    4618       120586 :       if (result)
    4619              :         return result;
    4620              :       else
    4621            0 :         return emit_move_multi_word (mode, x, y);
    4622              :     }
    4623              : 
    4624              :   if (GET_MODE_CLASS (mode) == MODE_CC)
    4625            0 :     return emit_move_ccmode (mode, x, y);
    4626              : 
    4627              :   /* Try using a move pattern for the corresponding integer mode.  This is
    4628              :      only safe when simplify_subreg can convert MODE constants into integer
    4629              :      constants.  At present, it can only do this reliably if the value
    4630              :      fits within a HOST_WIDE_INT.  */
    4631            1 :   if (!CONSTANT_P (y)
    4632            2 :       || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
    4633              :     {
    4634            1 :       rtx_insn *ret = emit_move_via_integer (mode, x, y, lra_in_progress);
    4635              : 
    4636            1 :       if (ret)
    4637              :         {
    4638            0 :           if (! lra_in_progress || recog (PATTERN (ret), ret, 0) >= 0)
    4639              :             return ret;
    4640              :         }
    4641              :     }
    4642              : 
    4643            1 :   return emit_move_multi_word (mode, x, y);
    4644              : }
    4645              : 
    4646              : /* Generate code to copy Y into X.
    4647              :    Both Y and X must have the same mode, except that
    4648              :    Y can be a constant with VOIDmode.
    4649              :    This mode cannot be BLKmode; use emit_block_move for that.
    4650              : 
    4651              :    Return the last instruction emitted.  */
    4652              : 
    4653              : rtx_insn *
    4654     71784030 : emit_move_insn (rtx x, rtx y)
    4655              : {
    4656     71784030 :   machine_mode mode = GET_MODE (x);
    4657     71784030 :   rtx y_cst = NULL_RTX;
    4658     71784030 :   rtx_insn *last_insn;
    4659     71784030 :   rtx set;
    4660              : 
    4661     71784030 :   gcc_assert (mode != BLKmode
    4662              :               && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
    4663              : 
    4664              :   /* If we have a copy that looks like one of the following patterns:
    4665              :        (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
    4666              :        (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
    4667              :        (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
    4668              :        (set (subreg:M1 (reg:M2 ...)) (constant C))
    4669              :      where mode M1 is equal in size to M2, try to detect whether the
    4670              :      mode change involves an implicit round trip through memory.
    4671              :      If so, see if we can avoid that by removing the subregs and
    4672              :      doing the move in mode M2 instead.  */
    4673              : 
    4674     71784030 :   rtx x_inner = NULL_RTX;
    4675     71784030 :   rtx y_inner = NULL_RTX;
    4676              : 
    4677     74592353 :   auto candidate_subreg_p = [&](rtx subreg) {
    4678      2808323 :     return (REG_P (SUBREG_REG (subreg))
    4679      8423148 :             && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
    4680              :                          GET_MODE_SIZE (GET_MODE (subreg)))
    4681      3196686 :             && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg)))
    4682      2808323 :                != CODE_FOR_nothing);
    4683              :   };
    4684              : 
    4685     71790268 :   auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
    4686         6238 :     return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
    4687         6238 :             && !push_operand (mem, GET_MODE (mem))
    4688              :             /* Not a candidate if innermode requires too much alignment.  */
    4689        12416 :             && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
    4690          232 :                 || targetm.slow_unaligned_access (GET_MODE (mem),
    4691          116 :                                                   MEM_ALIGN (mem))
    4692          232 :                 || !targetm.slow_unaligned_access (innermode,
    4693          116 :                                                    MEM_ALIGN (mem))));
    4694              :   };
    4695              : 
    4696     71784030 :   if (SUBREG_P (x) && candidate_subreg_p (x))
    4697        14717 :     x_inner = SUBREG_REG (x);
    4698              : 
    4699     71784030 :   if (SUBREG_P (y) && candidate_subreg_p (y))
    4700       337151 :     y_inner = SUBREG_REG (y);
    4701              : 
    4702     71784030 :   if (x_inner != NULL_RTX
    4703     71784030 :       && y_inner != NULL_RTX
    4704         1172 :       && GET_MODE (x_inner) == GET_MODE (y_inner)
    4705     71784775 :       && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
    4706              :     {
    4707          745 :       x = x_inner;
    4708          745 :       y = y_inner;
    4709          745 :       mode = GET_MODE (x_inner);
    4710              :     }
    4711     71783285 :   else if (x_inner != NULL_RTX
    4712        13972 :            && MEM_P (y)
    4713     71783609 :            && candidate_mem_p (GET_MODE (x_inner), y))
    4714              :     {
    4715          324 :       x = x_inner;
    4716          324 :       y = adjust_address (y, GET_MODE (x_inner), 0);
    4717          324 :       mode = GET_MODE (x_inner);
    4718              :     }
    4719     71782961 :   else if (y_inner != NULL_RTX
    4720       336406 :            && MEM_P (x)
    4721     71788875 :            && candidate_mem_p (GET_MODE (y_inner), x))
    4722              :     {
    4723         5854 :       x = adjust_address (x, GET_MODE (y_inner), 0);
    4724         5854 :       y = y_inner;
    4725         5854 :       mode = GET_MODE (y_inner);
    4726              :     }
    4727     71777107 :   else if (x_inner != NULL_RTX
    4728        13648 :            && CONSTANT_P (y)
    4729          475 :            && !targetm.can_change_mode_class (GET_MODE (x_inner),
    4730              :                                               mode, ALL_REGS)
    4731     71777582 :            && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
    4732              :     {
    4733          475 :       x = x_inner;
    4734          475 :       y = y_inner;
    4735          475 :       mode = GET_MODE (x_inner);
    4736              :     }
    4737              : 
    4738     71784030 :   if (CONSTANT_P (y))
    4739              :     {
    4740     16791444 :       if (optimize
    4741     13072185 :           && SCALAR_FLOAT_MODE_P (GET_MODE (x))
    4742     17566888 :           && (last_insn = compress_float_constant (x, y)))
    4743              :         return last_insn;
    4744              : 
    4745     16722055 :       y_cst = y;
    4746              : 
    4747     16722055 :       if (!targetm.legitimate_constant_p (mode, y))
    4748              :         {
    4749       514291 :           y = force_const_mem (mode, y);
    4750              : 
    4751              :           /* If the target's cannot_force_const_mem prevented the spill,
    4752              :              assume that the target's move expanders will also take care
    4753              :              of the non-legitimate constant.  */
    4754       514291 :           if (!y)
    4755              :             y = y_cst;
    4756              :           else
    4757       494304 :             y = use_anchored_address (y);
    4758              :         }
    4759              :     }
    4760              : 
    4761              :   /* If X or Y are memory references, verify that their addresses are valid
    4762              :      for the machine.  */
    4763     71714641 :   if (MEM_P (x)
    4764     87980792 :       && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
    4765     14004151 :                                          MEM_ADDR_SPACE (x))
    4766      2262174 :           && ! push_operand (x, GET_MODE (x))))
    4767          174 :     x = validize_mem (x);
    4768              : 
    4769     71714641 :   if (MEM_P (y)
    4770     89510565 :       && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
    4771     17795924 :                                         MEM_ADDR_SPACE (y)))
    4772         8709 :     y = validize_mem (y);
    4773              : 
    4774     71714641 :   gcc_assert (mode != BLKmode);
    4775              : 
    4776     71714641 :   last_insn = emit_move_insn_1 (x, y);
    4777              : 
    4778     16722055 :   if (y_cst && REG_P (x)
    4779     12278095 :       && (set = single_set (last_insn)) != NULL_RTX
    4780     12278095 :       && SET_DEST (set) == x
    4781     83978256 :       && ! rtx_equal_p (y_cst, SET_SRC (set)))
    4782      1275618 :     set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
    4783              : 
    4784              :   return last_insn;
    4785              : }
    4786              : 
    4787              : /* Generate the body of an instruction to copy Y into X.
    4788              :    It may be a list of insns, if one insn isn't enough.  */
    4789              : 
    4790              : rtx_insn *
    4791      6047456 : gen_move_insn (rtx x, rtx y)
    4792              : {
    4793      6047456 :   start_sequence ();
    4794      6047456 :   emit_move_insn_1 (x, y);
    4795      6047456 :   return end_sequence ();
    4796              : }
    4797              : 
    4798              : /* If Y is representable exactly in a narrower mode, and the target can
    4799              :    perform the extension directly from constant or memory, then emit the
    4800              :    move as an extension.  */
    4801              : 
    4802              : static rtx_insn *
    4803       775444 : compress_float_constant (rtx x, rtx y)
    4804              : {
    4805       775444 :   machine_mode dstmode = GET_MODE (x);
    4806       775444 :   machine_mode orig_srcmode = GET_MODE (y);
    4807       775444 :   machine_mode srcmode;
    4808       775444 :   const REAL_VALUE_TYPE *r;
    4809       775444 :   int oldcost, newcost;
    4810       775444 :   bool speed = optimize_insn_for_speed_p ();
    4811              : 
    4812       775444 :   r = CONST_DOUBLE_REAL_VALUE (y);
    4813              : 
    4814       775444 :   if (targetm.legitimate_constant_p (dstmode, y))
    4815       773299 :     oldcost = set_src_cost (y, orig_srcmode, speed);
    4816              :   else
    4817         2145 :     oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
    4818              : 
    4819      2745687 :   FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
    4820              :     {
    4821      2039632 :       enum insn_code ic;
    4822      2039632 :       rtx trunc_y;
    4823      2039632 :       rtx_insn *last_insn;
    4824              : 
    4825              :       /* Skip if the target can't extend this way.  */
    4826      2039632 :       ic = can_extend_p (dstmode, srcmode, 0);
    4827      2039632 :       if (ic == CODE_FOR_nothing)
    4828      1614997 :         continue;
    4829              : 
    4830              :       /* Skip if the narrowed value isn't exact.  */
    4831       424635 :       if (! exact_real_truncate (srcmode, r))
    4832        52652 :         continue;
    4833              : 
    4834       371983 :       trunc_y = const_double_from_real_value (*r, srcmode);
    4835              : 
    4836       371983 :       if (targetm.legitimate_constant_p (srcmode, trunc_y))
    4837              :         {
    4838              :           /* Skip if the target needs extra instructions to perform
    4839              :              the extension.  */
    4840       368040 :           if (!insn_operand_matches (ic, 1, trunc_y))
    4841         3999 :             continue;
    4842              :           /* This is valid, but may not be cheaper than the original. */
    4843       364041 :           newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
    4844              :                                   dstmode, speed);
    4845       364041 :           if (oldcost < newcost)
    4846       294652 :             continue;
    4847              :         }
    4848         3943 :       else if (float_extend_from_mem[dstmode][srcmode])
    4849              :         {
    4850            0 :           trunc_y = force_const_mem (srcmode, trunc_y);
    4851              :           /* This is valid, but may not be cheaper than the original. */
    4852            0 :           newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
    4853              :                                   dstmode, speed);
    4854            0 :           if (oldcost < newcost)
    4855            0 :             continue;
    4856            0 :           trunc_y = validize_mem (trunc_y);
    4857              :         }
    4858              :       else
    4859         3943 :         continue;
    4860              : 
    4861              :       /* For CSE's benefit, force the compressed constant pool entry
    4862              :          into a new pseudo.  This constant may be used in different modes,
    4863              :          and if not, combine will put things back together for us.  */
    4864        69389 :       trunc_y = force_reg (srcmode, trunc_y);
    4865              : 
    4866              :       /* If x is a hard register, perform the extension into a pseudo,
    4867              :          so that e.g. stack realignment code is aware of it.  */
    4868        69389 :       rtx target = x;
    4869        69389 :       if (REG_P (x) && HARD_REGISTER_P (x))
    4870            1 :         target = gen_reg_rtx (dstmode);
    4871              : 
    4872        69389 :       emit_unop_insn (ic, target, trunc_y, UNKNOWN);
    4873        69389 :       last_insn = get_last_insn ();
    4874              : 
    4875        69389 :       if (REG_P (target))
    4876        58715 :         set_unique_reg_note (last_insn, REG_EQUAL, y);
    4877              : 
    4878        69389 :       if (target != x)
    4879            1 :         return emit_move_insn (x, target);
    4880              :       return last_insn;
    4881              :     }
    4882              : 
    4883              :   return NULL;
    4884              : }
    4885              : 
    4886              : /* Pushing data onto the stack.  */
    4887              : 
    4888              : /* Push a block of length SIZE (perhaps variable)
    4889              :    and return an rtx to address the beginning of the block.
    4890              :    The value may be virtual_outgoing_args_rtx.
    4891              : 
    4892              :    EXTRA is the number of bytes of padding to push in addition to SIZE.
    4893              :    BELOW nonzero means this padding comes at low addresses;
    4894              :    otherwise, the padding comes at high addresses.  */
    4895              : 
    4896              : rtx
    4897       269027 : push_block (rtx size, poly_int64 extra, int below)
    4898              : {
    4899       269027 :   rtx temp;
    4900              : 
    4901       334016 :   size = convert_modes (Pmode, ptr_mode, size, 1);
    4902       269027 :   if (CONSTANT_P (size))
    4903       334016 :     anti_adjust_stack (plus_constant (Pmode, size, extra));
    4904            0 :   else if (REG_P (size) && known_eq (extra, 0))
    4905            0 :     anti_adjust_stack (size);
    4906              :   else
    4907              :     {
    4908            0 :       temp = copy_to_mode_reg (Pmode, size);
    4909            0 :       if (maybe_ne (extra, 0))
    4910            0 :         temp = expand_binop (Pmode, add_optab, temp,
    4911            0 :                              gen_int_mode (extra, Pmode),
    4912              :                              temp, 0, OPTAB_LIB_WIDEN);
    4913            0 :       anti_adjust_stack (temp);
    4914              :     }
    4915              : 
    4916       269027 :   if (STACK_GROWS_DOWNWARD)
    4917              :     {
    4918       269027 :       temp = virtual_outgoing_args_rtx;
    4919       269027 :       if (maybe_ne (extra, 0) && below)
    4920            0 :         temp = plus_constant (Pmode, temp, extra);
    4921              :     }
    4922              :   else
    4923              :     {
    4924              :       poly_int64 csize;
    4925              :       if (poly_int_rtx_p (size, &csize))
    4926              :         temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
    4927              :                               -csize - (below ? 0 : extra));
    4928              :       else if (maybe_ne (extra, 0) && !below)
    4929              :         temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
    4930              :                              negate_rtx (Pmode, plus_constant (Pmode, size,
    4931              :                                                                extra)));
    4932              :       else
    4933              :         temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
    4934              :                              negate_rtx (Pmode, size));
    4935              :     }
    4936              : 
    4937       269027 :   return memory_address (NARROWEST_INT_MODE, temp);
    4938              : }
    4939              : 
    4940              : /* A utility routine that returns the base of an auto-inc memory, or NULL.  */
    4941              : 
    4942              : static rtx
    4943      2583058 : mem_autoinc_base (rtx mem)
    4944              : {
    4945            0 :   if (MEM_P (mem))
    4946              :     {
    4947      1576150 :       rtx addr = XEXP (mem, 0);
    4948      1576150 :       if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
    4949      1030848 :         return XEXP (addr, 0);
    4950              :     }
    4951              :   return NULL;
    4952              : }
    4953              : 
    4954              : /* A utility routine used here, in reload, and in try_split.  The insns
    4955              :    after PREV up to and including LAST are known to adjust the stack,
    4956              :    with a final value of END_ARGS_SIZE.  Iterate backward from LAST
    4957              :    placing notes as appropriate.  PREV may be NULL, indicating the
    4958              :    entire insn sequence prior to LAST should be scanned.
    4959              : 
    4960              :    The set of allowed stack pointer modifications is small:
    4961              :      (1) One or more auto-inc style memory references (aka pushes),
    4962              :      (2) One or more addition/subtraction with the SP as destination,
    4963              :      (3) A single move insn with the SP as destination,
    4964              :      (4) A call_pop insn,
    4965              :      (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
    4966              : 
    4967              :    Insns in the sequence that do not modify the SP are ignored,
    4968              :    except for noreturn calls.
    4969              : 
    4970              :    The return value is the amount of adjustment that can be trivially
    4971              :    verified, via immediate operand or auto-inc.  If the adjustment
    4972              :    cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN.  */
    4973              : 
    4974              : poly_int64
    4975      4623164 : find_args_size_adjust (rtx_insn *insn)
    4976              : {
    4977      4623164 :   rtx dest, set, pat;
    4978      4623164 :   int i;
    4979              : 
    4980      4623164 :   pat = PATTERN (insn);
    4981      4623164 :   set = NULL;
    4982              : 
    4983              :   /* Look for a call_pop pattern.  */
    4984      4623164 :   if (CALL_P (insn))
    4985              :     {
    4986              :       /* We have to allow non-call_pop patterns for the case
    4987              :          of emit_single_push_insn of a TLS address.  */
    4988      2967932 :       if (GET_CODE (pat) != PARALLEL)
    4989      2953134 :         return 0;
    4990              : 
    4991              :       /* All call_pop have a stack pointer adjust in the parallel.
    4992              :          The call itself is always first, and the stack adjust is
    4993              :          usually last, so search from the end.  */
    4994        14798 :       for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
    4995              :         {
    4996        14798 :           set = XVECEXP (pat, 0, i);
    4997        14798 :           if (GET_CODE (set) != SET)
    4998            0 :             continue;
    4999        14798 :           dest = SET_DEST (set);
    5000        14798 :           if (dest == stack_pointer_rtx)
    5001              :             break;
    5002              :         }
    5003              :       /* We'd better have found the stack pointer adjust.  */
    5004        14798 :       if (i == 0)
    5005            0 :         return 0;
    5006              :       /* Fall through to process the extracted SET and DEST
    5007              :          as if it was a standalone insn.  */
    5008              :     }
    5009      1655232 :   else if (GET_CODE (pat) == SET)
    5010              :     set = pat;
    5011       259577 :   else if ((set = single_set (insn)) != NULL)
    5012              :     ;
    5013        47762 :   else if (GET_CODE (pat) == PARALLEL)
    5014              :     {
    5015              :       /* ??? Some older ports use a parallel with a stack adjust
    5016              :          and a store for a PUSH_ROUNDING pattern, rather than a
    5017              :          PRE/POST_MODIFY rtx.  Don't force them to update yet...  */
    5018              :       /* ??? See h8300 and m68k, pushqi1.  */
    5019            0 :       for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
    5020              :         {
    5021            0 :           set = XVECEXP (pat, 0, i);
    5022            0 :           if (GET_CODE (set) != SET)
    5023            0 :             continue;
    5024            0 :           dest = SET_DEST (set);
    5025            0 :           if (dest == stack_pointer_rtx)
    5026              :             break;
    5027              : 
    5028              :           /* We do not expect an auto-inc of the sp in the parallel.  */
    5029            0 :           gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
    5030            0 :           gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
    5031              :                                != stack_pointer_rtx);
    5032              :         }
    5033            0 :       if (i < 0)
    5034            0 :         return 0;
    5035              :     }
    5036              :   else
    5037        47762 :     return 0;
    5038              : 
    5039      1622268 :   dest = SET_DEST (set);
    5040              : 
    5041              :   /* Look for direct modifications of the stack pointer.  */
    5042      1622268 :   if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
    5043              :     {
    5044              :       /* Look for a trivial adjustment, otherwise assume nothing.  */
    5045              :       /* Note that the SPU restore_stack_block pattern refers to
    5046              :          the stack pointer in V4SImode.  Consider that non-trivial.  */
    5047       330739 :       poly_int64 offset;
    5048       330739 :       if (SCALAR_INT_MODE_P (GET_MODE (dest))
    5049       330739 :           && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
    5050       328268 :         return offset;
    5051              :       /* ??? Reload can generate no-op moves, which will be cleaned
    5052              :          up later.  Recognize it and continue searching.  */
    5053         2471 :       else if (rtx_equal_p (dest, SET_SRC (set)))
    5054            0 :         return 0;
    5055              :       else
    5056         2471 :         return HOST_WIDE_INT_MIN;
    5057              :     }
    5058              :   else
    5059              :     {
    5060      1291529 :       rtx mem, addr;
    5061              : 
    5062              :       /* Otherwise only think about autoinc patterns.  */
    5063      2336444 :       if (mem_autoinc_base (dest) == stack_pointer_rtx)
    5064              :         {
    5065       921947 :           mem = dest;
    5066      1275641 :           gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
    5067              :                                != stack_pointer_rtx);
    5068              :         }
    5069       547123 :       else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
    5070              :         mem = SET_SRC (set);
    5071              :       else
    5072       260681 :         return 0;
    5073              : 
    5074      1030848 :       addr = XEXP (mem, 0);
    5075      1030848 :       switch (GET_CODE (addr))
    5076              :         {
    5077       108901 :         case PRE_INC:
    5078       108901 :         case POST_INC:
    5079       217802 :           return GET_MODE_SIZE (GET_MODE (mem));
    5080       903862 :         case PRE_DEC:
    5081       903862 :         case POST_DEC:
    5082      1807724 :           return -GET_MODE_SIZE (GET_MODE (mem));
    5083        18085 :         case PRE_MODIFY:
    5084        18085 :         case POST_MODIFY:
    5085        18085 :           addr = XEXP (addr, 1);
    5086        18085 :           gcc_assert (GET_CODE (addr) == PLUS);
    5087        18085 :           gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
    5088        18085 :           return rtx_to_poly_int64 (XEXP (addr, 1));
    5089            0 :         default:
    5090            0 :           gcc_unreachable ();
    5091              :         }
    5092              :     }
    5093              : }
    5094              : 
    5095              : poly_int64
    5096       669457 : fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
    5097              :                        poly_int64 end_args_size)
    5098              : {
    5099       669457 :   poly_int64 args_size = end_args_size;
    5100       669457 :   bool saw_unknown = false;
    5101       669457 :   rtx_insn *insn;
    5102              : 
    5103      1910642 :   for (insn = last; insn != prev; insn = PREV_INSN (insn))
    5104              :     {
    5105      1241185 :       if (!NONDEBUG_INSN_P (insn))
    5106            0 :         continue;
    5107              : 
    5108              :       /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
    5109              :          a call argument containing a TLS address that itself requires
    5110              :          a call to __tls_get_addr.  The handling of stack_pointer_delta
    5111              :          in emit_single_push_insn is supposed to ensure that any such
    5112              :          notes are already correct.  */
    5113      1241185 :       rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
    5114      1241185 :       gcc_assert (!note || known_eq (args_size, get_args_size (note)));
    5115              : 
    5116      1241185 :       poly_int64 this_delta = find_args_size_adjust (insn);
    5117      1241185 :       if (known_eq (this_delta, 0))
    5118              :         {
    5119       612667 :           if (!CALL_P (insn)
    5120            9 :               || ACCUMULATE_OUTGOING_ARGS
    5121       306347 :               || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
    5122       306329 :             continue;
    5123              :         }
    5124              : 
    5125       934856 :       gcc_assert (!saw_unknown);
    5126       934856 :       if (known_eq (this_delta, HOST_WIDE_INT_MIN))
    5127         2444 :         saw_unknown = true;
    5128              : 
    5129       934856 :       if (!note)
    5130       934856 :         add_args_size_note (insn, args_size);
    5131       934856 :       if (STACK_GROWS_DOWNWARD)
    5132      1869712 :         this_delta = -poly_uint64 (this_delta);
    5133              : 
    5134       934856 :       if (saw_unknown)
    5135              :         args_size = HOST_WIDE_INT_MIN;
    5136              :       else
    5137      1241185 :         args_size -= this_delta;
    5138              :     }
    5139              : 
    5140       669457 :   return args_size;
    5141              : }
    5142              : 
    5143              : #ifdef PUSH_ROUNDING
    5144              : /* Emit single push insn.  */
    5145              : 
    5146              : static void
    5147      1847620 : emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
    5148              : {
    5149      1847620 :   rtx dest_addr;
    5150      3695240 :   poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
    5151      1847620 :   rtx dest;
    5152      1847620 :   enum insn_code icode;
    5153              : 
    5154              :   /* If there is push pattern, use it.  Otherwise try old way of throwing
    5155              :      MEM representing push operation to move expander.  */
    5156      1847620 :   icode = optab_handler (push_optab, mode);
    5157      1847620 :   if (icode != CODE_FOR_nothing)
    5158              :     {
    5159            0 :       class expand_operand ops[1];
    5160              : 
    5161            0 :       create_input_operand (&ops[0], x, mode);
    5162            0 :       if (maybe_expand_insn (icode, 1, ops))
    5163            0 :         return;
    5164              :     }
    5165      3695240 :   if (known_eq (GET_MODE_SIZE (mode), rounded_size))
    5166      3189867 :     dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
    5167              :   /* If we are to pad downward, adjust the stack pointer first and
    5168              :      then store X into the stack location using an offset.  This is
    5169              :      because emit_move_insn does not know how to pad; it does not have
    5170              :      access to type.  */
    5171       104812 :   else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
    5172              :     {
    5173            0 :       emit_move_insn (stack_pointer_rtx,
    5174            0 :                       expand_binop (Pmode,
    5175              :                                     STACK_GROWS_DOWNWARD ? sub_optab
    5176              :                                     : add_optab,
    5177              :                                     stack_pointer_rtx,
    5178            0 :                                     gen_int_mode (rounded_size, Pmode),
    5179              :                                     NULL_RTX, 0, OPTAB_LIB_WIDEN));
    5180              : 
    5181            0 :       poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
    5182            0 :       if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
    5183              :         /* We have already decremented the stack pointer, so get the
    5184              :            previous value.  */
    5185              :         offset += rounded_size;
    5186              : 
    5187            0 :       if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
    5188              :         /* We have already incremented the stack pointer, so get the
    5189              :            previous value.  */
    5190              :         offset -= rounded_size;
    5191              : 
    5192            0 :       dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
    5193              :     }
    5194              :   else
    5195              :     {
    5196              :       if (STACK_GROWS_DOWNWARD)
    5197              :         /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
    5198       105386 :         dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    5199              :       else
    5200              :         /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
    5201              :         dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
    5202              : 
    5203       105386 :       dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
    5204              :     }
    5205              : 
    5206      1847620 :   dest = gen_rtx_MEM (mode, dest_addr);
    5207              : 
    5208      1847620 :   if (type != 0)
    5209              :     {
    5210      1847573 :       set_mem_attributes (dest, type, 1);
    5211              : 
    5212      1847573 :       if (cfun->tail_call_marked)
    5213              :         /* Function incoming arguments may overlap with sibling call
    5214              :            outgoing arguments and we cannot allow reordering of reads
    5215              :            from function arguments with stores to outgoing arguments
    5216              :            of sibling calls.  */
    5217       143068 :         set_mem_alias_set (dest, 0);
    5218              :     }
    5219      1847620 :   emit_move_insn (dest, x);
    5220              : }
    5221              : 
    5222              : /* Emit and annotate a single push insn.  */
    5223              : 
    5224              : static void
    5225      1847620 : emit_single_push_insn (machine_mode mode, rtx x, tree type)
    5226              : {
    5227      1847620 :   poly_int64 delta, old_delta = stack_pointer_delta;
    5228      1847620 :   rtx_insn *prev = get_last_insn ();
    5229      1847620 :   rtx_insn *last;
    5230              : 
    5231      1847620 :   emit_single_push_insn_1 (mode, x, type);
    5232              : 
    5233              :   /* Adjust stack_pointer_delta to describe the situation after the push
    5234              :      we just performed.  Note that we must do this after the push rather
    5235              :      than before the push in case calculating X needs pushes and pops of
    5236              :      its own (e.g. if calling __tls_get_addr).  The REG_ARGS_SIZE notes
    5237              :      for such pushes and pops must not include the effect of the future
    5238              :      push of X.  */
    5239      3695240 :   stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
    5240              : 
    5241      1847620 :   last = get_last_insn ();
    5242              : 
    5243              :   /* Notice the common case where we emitted exactly one insn.  */
    5244      1847620 :   if (PREV_INSN (last) == prev)
    5245              :     {
    5246      1736570 :       add_args_size_note (last, stack_pointer_delta);
    5247      1736570 :       return;
    5248              :     }
    5249              : 
    5250       111050 :   delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
    5251       111050 :   gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
    5252              :               || known_eq (delta, old_delta));
    5253              : }
    5254              : #endif
    5255              : 
    5256              : /* If reading SIZE bytes from X will end up reading from
    5257              :    Y return the number of bytes that overlap.  Return -1
    5258              :    if there is no overlap or -2 if we can't determine
    5259              :    (for example when X and Y have different base registers).  */
    5260              : 
    5261              : static int
    5262            0 : memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
    5263              : {
    5264            0 :   rtx tmp = plus_constant (Pmode, x, size);
    5265            0 :   rtx sub = simplify_gen_binary (MINUS, Pmode, tmp, y);
    5266              : 
    5267            0 :   if (!CONST_INT_P (sub))
    5268              :     return -2;
    5269              : 
    5270            0 :   HOST_WIDE_INT val = INTVAL (sub);
    5271              : 
    5272            0 :   return IN_RANGE (val, 1, size) ? val : -1;
    5273              : }
    5274              : 
    5275              : /* Generate code to push X onto the stack, assuming it has mode MODE and
    5276              :    type TYPE.
    5277              :    MODE is redundant except when X is a CONST_INT (since they don't
    5278              :    carry mode info).
    5279              :    SIZE is an rtx for the size of data to be copied (in bytes),
    5280              :    needed only if X is BLKmode.
    5281              :    Return true if successful.  May return false if asked to push a
    5282              :    partial argument during a sibcall optimization (as specified by
    5283              :    SIBCALL_P) and the incoming and outgoing pointers cannot be shown
    5284              :    to not overlap.
    5285              : 
    5286              :    ALIGN (in bits) is maximum alignment we can assume.
    5287              : 
    5288              :    If PARTIAL and REG are both nonzero, then copy that many of the first
    5289              :    bytes of X into registers starting with REG, and push the rest of X.
    5290              :    The amount of space pushed is decreased by PARTIAL bytes.
    5291              :    REG must be a hard register in this case.
    5292              :    If REG is zero but PARTIAL is not, take any all others actions for an
    5293              :    argument partially in registers, but do not actually load any
    5294              :    registers.
    5295              : 
    5296              :    EXTRA is the amount in bytes of extra space to leave next to this arg.
    5297              :    This is ignored if an argument block has already been allocated.
    5298              : 
    5299              :    On a machine that lacks real push insns, ARGS_ADDR is the address of
    5300              :    the bottom of the argument block for this call.  We use indexing off there
    5301              :    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
    5302              :    argument block has not been preallocated.
    5303              : 
    5304              :    ARGS_SO_FAR is the size of args previously pushed for this call.
    5305              : 
    5306              :    REG_PARM_STACK_SPACE is nonzero if functions require stack space
    5307              :    for arguments passed in registers.  If nonzero, it will be the number
    5308              :    of bytes required.  */
    5309              : 
    5310              : bool
    5311      2172028 : emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
    5312              :                 unsigned int align, int partial, rtx reg, poly_int64 extra,
    5313              :                 rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
    5314              :                 rtx alignment_pad, bool sibcall_p)
    5315              : {
    5316      2172028 :   rtx xinner;
    5317      2172028 :   pad_direction stack_direction
    5318              :     = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
    5319              : 
    5320              :   /* Decide where to pad the argument: PAD_DOWNWARD for below,
    5321              :      PAD_UPWARD for above, or PAD_NONE for don't pad it.
    5322              :      Default is below for small data on big-endian machines; else above.  */
    5323      2172028 :   pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
    5324              : 
    5325              :   /* Invert direction if stack is post-decrement.
    5326              :      FIXME: why?  */
    5327      2172028 :   if (STACK_PUSH_CODE == POST_DEC)
    5328              :     if (where_pad != PAD_NONE)
    5329              :       where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
    5330              : 
    5331      2172028 :   xinner = x;
    5332              : 
    5333      2172028 :   int nregs = partial / UNITS_PER_WORD;
    5334      2172028 :   rtx *tmp_regs = NULL;
    5335      2172028 :   int overlapping = 0;
    5336              : 
    5337      2172028 :   if (mode == BLKmode
    5338              :       || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
    5339              :     {
    5340              :       /* Copy a block into the stack, entirely or partially.  */
    5341              : 
    5342       269117 :       rtx temp;
    5343       269117 :       int used;
    5344       269117 :       int offset;
    5345       269117 :       int skip;
    5346              : 
    5347       269117 :       offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
    5348       269117 :       used = partial - offset;
    5349              : 
    5350       269117 :       if (mode != BLKmode)
    5351              :         {
    5352              :           /* A value is to be stored in an insufficiently aligned
    5353              :              stack slot; copy via a suitably aligned slot if
    5354              :              necessary.  */
    5355              :           size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
    5356              :           if (!MEM_P (xinner))
    5357              :             {
    5358              :               temp = assign_temp (type, 1, 1);
    5359              :               emit_move_insn (temp, xinner);
    5360              :               xinner = temp;
    5361              :             }
    5362              :         }
    5363              : 
    5364       269117 :       gcc_assert (size);
    5365              : 
    5366              :       /* USED is now the # of bytes we need not copy to the stack
    5367              :          because registers will take care of them.  */
    5368              : 
    5369       269117 :       if (partial != 0)
    5370            0 :         xinner = adjust_address (xinner, BLKmode, used);
    5371              : 
    5372              :       /* If the partial register-part of the arg counts in its stack size,
    5373              :          skip the part of stack space corresponding to the registers.
    5374              :          Otherwise, start copying to the beginning of the stack space,
    5375              :          by setting SKIP to 0.  */
    5376       269117 :       skip = (reg_parm_stack_space == 0) ? 0 : used;
    5377              : 
    5378              : #ifdef PUSH_ROUNDING
    5379              :       /* NB: Let the backend known the number of bytes to push and
    5380              :          decide if push insns should be generated.  */
    5381       269117 :       unsigned int push_size;
    5382       269117 :       if (CONST_INT_P (size))
    5383       269117 :         push_size = INTVAL (size);
    5384              :       else
    5385              :         push_size = 0;
    5386              : 
    5387              :       /* Do it with several push insns if that doesn't take lots of insns
    5388              :          and if there is no difficulty with push insns that skip bytes
    5389              :          on the stack for alignment purposes.  */
    5390       269117 :       if (args_addr == 0
    5391       269063 :           && targetm.calls.push_argument (push_size)
    5392         3783 :           && CONST_INT_P (size)
    5393         3783 :           && skip == 0
    5394         3783 :           && MEM_ALIGN (xinner) >= align
    5395         2937 :           && can_move_by_pieces ((unsigned) INTVAL (size) - used, align)
    5396              :           /* Here we avoid the case of a structure whose weak alignment
    5397              :              forces many pushes of a small amount of data,
    5398              :              and such small pushes do rounding that causes trouble.  */
    5399         2937 :           && ((!targetm.slow_unaligned_access (word_mode, align))
    5400            0 :               || align >= BIGGEST_ALIGNMENT
    5401            0 :               || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
    5402              :                            align / BITS_PER_UNIT))
    5403       272054 :           && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
    5404              :         {
    5405              :           /* Push padding now if padding above and stack grows down,
    5406              :              or if padding below and stack grows up.
    5407              :              But if space already allocated, this has already been done.  */
    5408           45 :           if (maybe_ne (extra, 0)
    5409              :               && args_addr == 0
    5410            0 :               && where_pad != PAD_NONE
    5411           45 :               && where_pad != stack_direction)
    5412            0 :             anti_adjust_stack (gen_int_mode (extra, Pmode));
    5413              : 
    5414           45 :           move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
    5415              :                           RETURN_BEGIN);
    5416              :         }
    5417              :       else
    5418              : #endif /* PUSH_ROUNDING  */
    5419              :         {
    5420       269072 :           rtx target;
    5421              : 
    5422              :           /* Otherwise make space on the stack and copy the data
    5423              :              to the address of that space.  */
    5424              : 
    5425              :           /* Deduct words put into registers from the size we must copy.  */
    5426       269072 :           if (partial != 0)
    5427              :             {
    5428            0 :               if (CONST_INT_P (size))
    5429            0 :                 size = GEN_INT (INTVAL (size) - used);
    5430              :               else
    5431            0 :                 size = expand_binop (GET_MODE (size), sub_optab, size,
    5432            0 :                                      gen_int_mode (used, GET_MODE (size)),
    5433              :                                      NULL_RTX, 0, OPTAB_LIB_WIDEN);
    5434              :             }
    5435              : 
    5436              :           /* Get the address of the stack space.
    5437              :              In this case, we do not deal with EXTRA separately.
    5438              :              A single stack adjust will do.  */
    5439       269072 :           poly_int64 const_args_so_far;
    5440       269072 :           if (! args_addr)
    5441              :             {
    5442       269018 :               temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
    5443       269018 :               extra = 0;
    5444              :             }
    5445           54 :           else if (poly_int_rtx_p (args_so_far, &const_args_so_far))
    5446           72 :             temp = memory_address (BLKmode,
    5447              :                                    plus_constant (Pmode, args_addr,
    5448              :                                                   skip + const_args_so_far));
    5449              :           else
    5450            0 :             temp = memory_address (BLKmode,
    5451              :                                    plus_constant (Pmode,
    5452              :                                                   gen_rtx_PLUS (Pmode,
    5453              :                                                                 args_addr,
    5454              :                                                                 args_so_far),
    5455              :                                                   skip));
    5456              : 
    5457       269072 :           if (!ACCUMULATE_OUTGOING_ARGS)
    5458              :             {
    5459              :               /* If the source is referenced relative to the stack pointer,
    5460              :                  copy it to another register to stabilize it.  We do not need
    5461              :                  to do this if we know that we won't be changing sp.  */
    5462              : 
    5463       269072 :               if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
    5464       269072 :                   || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
    5465       269018 :                 temp = copy_to_reg (temp);
    5466              :             }
    5467              : 
    5468       269072 :           target = gen_rtx_MEM (BLKmode, temp);
    5469              : 
    5470              :           /* We do *not* set_mem_attributes here, because incoming arguments
    5471              :              may overlap with sibling call outgoing arguments and we cannot
    5472              :              allow reordering of reads from function arguments with stores
    5473              :              to outgoing arguments of sibling calls.  We do, however, want
    5474              :              to record the alignment of the stack slot.  */
    5475              :           /* ALIGN may well be better aligned than TYPE, e.g. due to
    5476              :              PARM_BOUNDARY.  Assume the caller isn't lying.  */
    5477       269072 :           set_mem_align (target, align);
    5478              : 
    5479              :           /* If part should go in registers and pushing to that part would
    5480              :              overwrite some of the values that need to go into regs, load the
    5481              :              overlapping values into temporary pseudos to be moved into the hard
    5482              :              regs at the end after the stack pushing has completed.
    5483              :              We cannot load them directly into the hard regs here because
    5484              :              they can be clobbered by the block move expansions.
    5485              :              See PR 65358.  */
    5486              : 
    5487       269072 :           if (partial > 0 && reg != 0 && mode == BLKmode
    5488            0 :               && GET_CODE (reg) != PARALLEL)
    5489              :             {
    5490            0 :               overlapping = memory_load_overlap (XEXP (x, 0), temp, partial);
    5491            0 :               if (overlapping > 0)
    5492              :                 {
    5493            0 :                   gcc_assert (overlapping % UNITS_PER_WORD == 0);
    5494            0 :                   overlapping /= UNITS_PER_WORD;
    5495              : 
    5496            0 :                   tmp_regs = XALLOCAVEC (rtx, overlapping);
    5497              : 
    5498            0 :                   for (int i = 0; i < overlapping; i++)
    5499            0 :                     tmp_regs[i] = gen_reg_rtx (word_mode);
    5500              : 
    5501            0 :                   for (int i = 0; i < overlapping; i++)
    5502            0 :                     emit_move_insn (tmp_regs[i],
    5503            0 :                                     operand_subword_force (target, i, mode));
    5504              :                 }
    5505            0 :               else if (overlapping == -1)
    5506              :                 overlapping = 0;
    5507              :               /* Could not determine whether there is overlap.
    5508              :                  Fail the sibcall.  */
    5509              :               else
    5510              :                 {
    5511            0 :                   overlapping = 0;
    5512            0 :                   if (sibcall_p)
    5513      2172028 :                     return false;
    5514              :                 }
    5515              :             }
    5516              : 
    5517              :           /* If source is a constant VAR_DECL with a simple constructor,
    5518              :              store the constructor to the stack instead of moving it.  */
    5519       269072 :           const_tree decl;
    5520       269072 :           HOST_WIDE_INT sz;
    5521       269072 :           if (partial == 0
    5522       269072 :               && MEM_P (xinner)
    5523       269072 :               && SYMBOL_REF_P (XEXP (xinner, 0))
    5524        82591 :               && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
    5525        82591 :               && VAR_P (decl)
    5526        82591 :               && TREE_READONLY (decl)
    5527         5229 :               && !TREE_SIDE_EFFECTS (decl)
    5528         5229 :               && immediate_const_ctor_p (DECL_INITIAL (decl), 2)
    5529            9 :               && (sz = int_expr_size (DECL_INITIAL (decl))) > 0
    5530            9 :               && CONST_INT_P (size)
    5531       269081 :               && INTVAL (size) == sz)
    5532            3 :             store_constructor (DECL_INITIAL (decl), target, 0, sz, false);
    5533              :           else
    5534       269069 :             emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
    5535              :         }
    5536              :     }
    5537      1902911 :   else if (partial > 0)
    5538              :     {
    5539              :       /* Scalar partly in registers.  This case is only supported
    5540              :          for fixed-wdth modes.  */
    5541            0 :       int num_words = GET_MODE_SIZE (mode).to_constant ();
    5542            0 :       num_words /= UNITS_PER_WORD;
    5543            0 :       int i;
    5544            0 :       int not_stack;
    5545              :       /* # bytes of start of argument
    5546              :          that we must make space for but need not store.  */
    5547            0 :       int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
    5548            0 :       int args_offset = INTVAL (args_so_far);
    5549            0 :       int skip;
    5550              : 
    5551              :       /* Push padding now if padding above and stack grows down,
    5552              :          or if padding below and stack grows up.
    5553              :          But if space already allocated, this has already been done.  */
    5554            0 :       if (maybe_ne (extra, 0)
    5555            0 :           && args_addr == 0
    5556            0 :           && where_pad != PAD_NONE
    5557            0 :           && where_pad != stack_direction)
    5558            0 :         anti_adjust_stack (gen_int_mode (extra, Pmode));
    5559              : 
    5560              :       /* If we make space by pushing it, we might as well push
    5561              :          the real data.  Otherwise, we can leave OFFSET nonzero
    5562              :          and leave the space uninitialized.  */
    5563            0 :       if (args_addr == 0)
    5564            0 :         offset = 0;
    5565              : 
    5566              :       /* Now NOT_STACK gets the number of words that we don't need to
    5567              :          allocate on the stack.  Convert OFFSET to words too.  */
    5568            0 :       not_stack = (partial - offset) / UNITS_PER_WORD;
    5569            0 :       offset /= UNITS_PER_WORD;
    5570              : 
    5571              :       /* If the partial register-part of the arg counts in its stack size,
    5572              :          skip the part of stack space corresponding to the registers.
    5573              :          Otherwise, start copying to the beginning of the stack space,
    5574              :          by setting SKIP to 0.  */
    5575            0 :       skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
    5576              : 
    5577            0 :       if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
    5578            0 :         x = validize_mem (force_const_mem (mode, x));
    5579              : 
    5580              :       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
    5581              :          SUBREGs of such registers are not allowed.  */
    5582            0 :       if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
    5583            0 :            && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
    5584            0 :         x = copy_to_reg (x);
    5585              : 
    5586              :       /* Loop over all the words allocated on the stack for this arg.  */
    5587              :       /* We can do it by words, because any scalar bigger than a word
    5588              :          has a size a multiple of a word.  */
    5589            0 :       tree word_mode_type = lang_hooks.types.type_for_mode (word_mode, 1);
    5590            0 :       for (i = num_words - 1; i >= not_stack; i--)
    5591            0 :         if (i >= not_stack + offset)
    5592            0 :           if (!emit_push_insn (operand_subword_force (x, i, mode),
    5593              :                           word_mode, word_mode_type, NULL_RTX, align, 0,
    5594              :                           NULL_RTX, 0, args_addr,
    5595            0 :                           GEN_INT (args_offset + ((i - not_stack + skip)
    5596              :                                                   * UNITS_PER_WORD)),
    5597              :                           reg_parm_stack_space, alignment_pad, sibcall_p))
    5598      2172028 :             return false;
    5599              :     }
    5600              :   else
    5601              :     {
    5602      1902911 :       rtx addr;
    5603      1902911 :       rtx dest;
    5604              : 
    5605              :       /* Push padding now if padding above and stack grows down,
    5606              :          or if padding below and stack grows up.
    5607              :          But if space already allocated, this has already been done.  */
    5608      1902911 :       if (maybe_ne (extra, 0)
    5609            0 :           && args_addr == 0
    5610            0 :           && where_pad != PAD_NONE
    5611      1902911 :           && where_pad != stack_direction)
    5612            0 :         anti_adjust_stack (gen_int_mode (extra, Pmode));
    5613              : 
    5614              : #ifdef PUSH_ROUNDING
    5615      1902911 :       if (args_addr == 0 && targetm.calls.push_argument (0))
    5616      1847573 :         emit_single_push_insn (mode, x, type);
    5617              :       else
    5618              : #endif
    5619              :         {
    5620        63572 :           addr = simplify_gen_binary (PLUS, Pmode, args_addr, args_so_far);
    5621        55338 :           dest = gen_rtx_MEM (mode, memory_address (mode, addr));
    5622              : 
    5623              :           /* We do *not* set_mem_attributes here, because incoming arguments
    5624              :              may overlap with sibling call outgoing arguments and we cannot
    5625              :              allow reordering of reads from function arguments with stores
    5626              :              to outgoing arguments of sibling calls.  We do, however, want
    5627              :              to record the alignment of the stack slot.  */
    5628              :           /* ALIGN may well be better aligned than TYPE, e.g. due to
    5629              :              PARM_BOUNDARY.  Assume the caller isn't lying.  */
    5630        55338 :           set_mem_align (dest, align);
    5631              : 
    5632        55338 :           emit_move_insn (dest, x);
    5633              :         }
    5634              :     }
    5635              : 
    5636              :   /* Move the partial arguments into the registers and any overlapping
    5637              :      values that we moved into the pseudos in tmp_regs.  */
    5638      2172028 :   if (partial > 0 && reg != 0)
    5639              :     {
    5640              :       /* Handle calls that pass values in multiple non-contiguous locations.
    5641              :          The Irix 6 ABI has examples of this.  */
    5642            0 :       if (GET_CODE (reg) == PARALLEL)
    5643            0 :         emit_group_load (reg, x, type, -1);
    5644              :       else
    5645              :         {
    5646            0 :           gcc_assert (partial % UNITS_PER_WORD == 0);
    5647            0 :           move_block_to_reg (REGNO (reg), x, nregs - overlapping, mode);
    5648              : 
    5649            0 :           for (int i = 0; i < overlapping; i++)
    5650            0 :             emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg)
    5651            0 :                                                     + nregs - overlapping + i),
    5652            0 :                             tmp_regs[i]);
    5653              : 
    5654              :         }
    5655              :     }
    5656              : 
    5657      2172028 :   if (maybe_ne (extra, 0) && args_addr == 0 && where_pad == stack_direction)
    5658            0 :     anti_adjust_stack (gen_int_mode (extra, Pmode));
    5659              : 
    5660      2172028 :   if (alignment_pad && args_addr == 0)
    5661      2116636 :     anti_adjust_stack (alignment_pad);
    5662              : 
    5663              :   return true;
    5664              : }
    5665              : 
    5666              : /* Return X if X can be used as a subtarget in a sequence of arithmetic
    5667              :    operations.  */
    5668              : 
    5669              : static rtx
    5670    205580543 : get_subtarget (rtx x)
    5671              : {
    5672    205580543 :   return (optimize
    5673     52867303 :           || x == 0
    5674              :            /* Only registers can be subtargets.  */
    5675     17700627 :            || !REG_P (x)
    5676              :            /* Don't use hard regs to avoid extending their life.  */
    5677     12023498 :            || REGNO (x) < FIRST_PSEUDO_REGISTER
    5678    205580543 :           ? 0 : x);
    5679              : }
    5680              : 
    5681              : /* A subroutine of expand_assignment.  Optimize FIELD op= VAL, where
    5682              :    FIELD is a bitfield.  Returns true if the optimization was successful,
    5683              :    and there's nothing else to do.  */
    5684              : 
    5685              : static bool
    5686      4794350 : optimize_bitfield_assignment_op (poly_uint64 pbitsize,
    5687              :                                  poly_uint64 pbitpos,
    5688              :                                  poly_uint64 pbitregion_start,
    5689              :                                  poly_uint64 pbitregion_end,
    5690              :                                  machine_mode mode1, rtx str_rtx,
    5691              :                                  tree to, tree src, bool reverse)
    5692              : {
    5693              :   /* str_mode is not guaranteed to be a scalar type.  */
    5694      4794350 :   machine_mode str_mode = GET_MODE (str_rtx);
    5695      4794350 :   unsigned int str_bitsize;
    5696      4794350 :   tree op0, op1;
    5697      4794350 :   rtx value, result;
    5698      4794350 :   optab binop;
    5699      4794350 :   gimple *srcstmt;
    5700      4794350 :   enum tree_code code;
    5701              : 
    5702      4794350 :   unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
    5703      4794350 :   if (mode1 != VOIDmode
    5704        67339 :       || !pbitsize.is_constant (&bitsize)
    5705        67339 :       || !pbitpos.is_constant (&bitpos)
    5706        67339 :       || !pbitregion_start.is_constant (&bitregion_start)
    5707        67339 :       || !pbitregion_end.is_constant (&bitregion_end)
    5708        68023 :       || bitsize >= BITS_PER_WORD
    5709        67068 :       || !GET_MODE_BITSIZE (str_mode).is_constant (&str_bitsize)
    5710        67752 :       || str_bitsize > BITS_PER_WORD
    5711        61672 :       || TREE_SIDE_EFFECTS (to)
    5712      4855893 :       || TREE_THIS_VOLATILE (to))
    5713              :     return false;
    5714              : 
    5715        61543 :   STRIP_NOPS (src);
    5716        61543 :   if (TREE_CODE (src) != SSA_NAME)
    5717              :     return false;
    5718        20308 :   if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
    5719              :     return false;
    5720              : 
    5721        18709 :   srcstmt = get_gimple_for_ssa_name (src);
    5722        18709 :   if (!srcstmt
    5723         4978 :       || !is_gimple_assign (srcstmt)
    5724        23687 :       || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
    5725              :     return false;
    5726              : 
    5727          845 :   code = gimple_assign_rhs_code (srcstmt);
    5728              : 
    5729          845 :   op0 = gimple_assign_rhs1 (srcstmt);
    5730              : 
    5731              :   /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
    5732              :      to find its initialization.  Hopefully the initialization will
    5733              :      be from a bitfield load.  */
    5734          845 :   if (TREE_CODE (op0) == SSA_NAME)
    5735              :     {
    5736          845 :       gimple *op0stmt = get_gimple_for_ssa_name (op0);
    5737              : 
    5738              :       /* We want to eventually have OP0 be the same as TO, which
    5739              :          should be a bitfield.  */
    5740          845 :       if (!op0stmt
    5741          775 :           || !is_gimple_assign (op0stmt)
    5742         1620 :           || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
    5743              :         return false;
    5744          548 :       op0 = gimple_assign_rhs1 (op0stmt);
    5745              :     }
    5746              : 
    5747          548 :   op1 = gimple_assign_rhs2 (srcstmt);
    5748              : 
    5749          548 :   if (!operand_equal_p (to, op0, 0))
    5750              :     return false;
    5751              : 
    5752          463 :   if (MEM_P (str_rtx))
    5753              :     {
    5754          422 :       unsigned HOST_WIDE_INT offset1;
    5755              : 
    5756          422 :       if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
    5757           82 :         str_bitsize = BITS_PER_WORD;
    5758              : 
    5759          422 :       scalar_int_mode best_mode;
    5760          422 :       if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
    5761          422 :                           MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
    5762            0 :         return false;
    5763          422 :       str_mode = best_mode;
    5764          422 :       str_bitsize = GET_MODE_BITSIZE (best_mode);
    5765              : 
    5766          422 :       offset1 = bitpos;
    5767          422 :       bitpos %= str_bitsize;
    5768          422 :       offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
    5769          422 :       str_rtx = adjust_address (str_rtx, str_mode, offset1);
    5770              :     }
    5771           41 :   else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
    5772              :     return false;
    5773              : 
    5774              :   /* If the bit field covers the whole REG/MEM, store_field
    5775              :      will likely generate better code.  */
    5776          463 :   if (bitsize >= str_bitsize)
    5777              :     return false;
    5778              : 
    5779              :   /* We can't handle fields split across multiple entities.  */
    5780          463 :   if (bitpos + bitsize > str_bitsize)
    5781              :     return false;
    5782              : 
    5783          463 :   if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
    5784            0 :     bitpos = str_bitsize - bitpos - bitsize;
    5785              : 
    5786          463 :   switch (code)
    5787              :     {
    5788          140 :     case PLUS_EXPR:
    5789          140 :     case MINUS_EXPR:
    5790              :       /* For now, just optimize the case of the topmost bitfield
    5791              :          where we don't need to do any masking and also
    5792              :          1 bit bitfields where xor can be used.
    5793              :          We might win by one instruction for the other bitfields
    5794              :          too if insv/extv instructions aren't used, so that
    5795              :          can be added later.  */
    5796          140 :       if ((reverse || bitpos + bitsize != str_bitsize)
    5797           96 :           && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
    5798              :         break;
    5799              : 
    5800           69 :       value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
    5801           69 :       value = convert_modes (str_mode,
    5802           69 :                              TYPE_MODE (TREE_TYPE (op1)), value,
    5803           69 :                              TYPE_UNSIGNED (TREE_TYPE (op1)));
    5804              : 
    5805              :       /* We may be accessing data outside the field, which means
    5806              :          we can alias adjacent data.  */
    5807           69 :       if (MEM_P (str_rtx))
    5808              :         {
    5809           69 :           str_rtx = shallow_copy_rtx (str_rtx);
    5810           69 :           set_mem_alias_set (str_rtx, 0);
    5811           69 :           set_mem_expr (str_rtx, 0);
    5812              :         }
    5813              : 
    5814           69 :       if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
    5815              :         {
    5816           25 :           value = expand_and (str_mode, value, const1_rtx, NULL);
    5817           25 :           binop = xor_optab;
    5818              :         }
    5819              :       else
    5820           44 :         binop = code == PLUS_EXPR ? add_optab : sub_optab;
    5821              : 
    5822           69 :       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
    5823           69 :       if (reverse)
    5824            0 :         value = flip_storage_order (str_mode, value);
    5825           69 :       result = expand_binop (str_mode, binop, str_rtx,
    5826              :                              value, str_rtx, 1, OPTAB_WIDEN);
    5827           69 :       if (result != str_rtx)
    5828            0 :         emit_move_insn (str_rtx, result);
    5829              :       return true;
    5830              : 
    5831          255 :     case BIT_IOR_EXPR:
    5832          255 :     case BIT_XOR_EXPR:
    5833          255 :       if (TREE_CODE (op1) != INTEGER_CST)
    5834              :         break;
    5835           97 :       value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
    5836           97 :       value = convert_modes (str_mode,
    5837           97 :                              TYPE_MODE (TREE_TYPE (op1)), value,
    5838           97 :                              TYPE_UNSIGNED (TREE_TYPE (op1)));
    5839              : 
    5840              :       /* We may be accessing data outside the field, which means
    5841              :          we can alias adjacent data.  */
    5842           97 :       if (MEM_P (str_rtx))
    5843              :         {
    5844           61 :           str_rtx = shallow_copy_rtx (str_rtx);
    5845           61 :           set_mem_alias_set (str_rtx, 0);
    5846           61 :           set_mem_expr (str_rtx, 0);
    5847              :         }
    5848              : 
    5849           97 :       binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
    5850           97 :       if (bitpos + bitsize != str_bitsize)
    5851              :         {
    5852           55 :           rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
    5853              :                                    str_mode);
    5854           55 :           value = expand_and (str_mode, value, mask, NULL_RTX);
    5855              :         }
    5856           97 :       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
    5857           97 :       if (reverse)
    5858            0 :         value = flip_storage_order (str_mode, value);
    5859           97 :       result = expand_binop (str_mode, binop, str_rtx,
    5860              :                              value, str_rtx, 1, OPTAB_WIDEN);
    5861           97 :       if (result != str_rtx)
    5862            0 :         emit_move_insn (str_rtx, result);
    5863              :       return true;
    5864              : 
    5865              :     default:
    5866              :       break;
    5867              :     }
    5868              : 
    5869              :   return false;
    5870              : }
    5871              : 
    5872              : /* In the C++ memory model, consecutive bit fields in a structure are
    5873              :    considered one memory location.
    5874              : 
    5875              :    Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
    5876              :    returns the bit range of consecutive bits in which this COMPONENT_REF
    5877              :    belongs.  The values are returned in *BITSTART and *BITEND.  *BITPOS
    5878              :    and *OFFSET may be adjusted in the process.
    5879              : 
    5880              :    If the access does not need to be restricted, 0 is returned in both
    5881              :    *BITSTART and *BITEND.  */
    5882              : 
    5883              : void
    5884       937281 : get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
    5885              :                poly_int64 *bitpos, tree *offset)
    5886              : {
    5887       937281 :   poly_int64 bitoffset;
    5888       937281 :   tree field, repr;
    5889              : 
    5890       937281 :   gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
    5891              : 
    5892       937281 :   field = TREE_OPERAND (exp, 1);
    5893       937281 :   repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
    5894              :   /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
    5895              :      need to limit the range we can access.  */
    5896       937281 :   if (!repr)
    5897              :     {
    5898           65 :       *bitstart = *bitend = 0;
    5899           65 :       return;
    5900              :     }
    5901              : 
    5902              :   /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
    5903              :      part of a larger bit field, then the representative does not serve any
    5904              :      useful purpose.  This can occur in Ada.  */
    5905       937216 :   if (handled_component_p (TREE_OPERAND (exp, 0)))
    5906              :     {
    5907       506724 :       machine_mode rmode;
    5908       506724 :       poly_int64 rbitsize, rbitpos;
    5909       506724 :       tree roffset;
    5910       506724 :       int unsignedp, reversep, volatilep = 0;
    5911       506724 :       get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
    5912              :                            &roffset, &rmode, &unsignedp, &reversep,
    5913              :                            &volatilep);
    5914      1013448 :       if (!multiple_p (rbitpos, BITS_PER_UNIT))
    5915              :         {
    5916            0 :           *bitstart = *bitend = 0;
    5917            0 :           return;
    5918              :         }
    5919              :     }
    5920              : 
    5921              :   /* Compute the adjustment to bitpos from the offset of the field
    5922              :      relative to the representative.  DECL_FIELD_OFFSET of field and
    5923              :      repr are the same by construction if they are not constants,
    5924              :      see finish_bitfield_layout.  */
    5925       937216 :   poly_uint64 field_offset, repr_offset;
    5926       937216 :   if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
    5927      1874427 :       && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
    5928       937211 :     bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
    5929              :   else
    5930              :     bitoffset = 0;
    5931       937216 :   bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
    5932       937216 :                 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
    5933              : 
    5934              :   /* If the adjustment is larger than bitpos, we would have a negative bit
    5935              :      position for the lower bound and this may wreak havoc later.  Adjust
    5936              :      offset and bitpos to make the lower bound non-negative in that case.  */
    5937       937216 :   if (maybe_gt (bitoffset, *bitpos))
    5938              :     {
    5939            9 :       poly_int64 adjust_bits = upper_bound (bitoffset, *bitpos) - *bitpos;
    5940            9 :       poly_int64 adjust_bytes = exact_div (adjust_bits, BITS_PER_UNIT);
    5941              : 
    5942            9 :       *bitpos += adjust_bits;
    5943            9 :       if (*offset == NULL_TREE)
    5944            5 :         *offset = size_int (-adjust_bytes);
    5945              :       else
    5946            4 :         *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
    5947            9 :       *bitstart = 0;
    5948              :     }
    5949              :   else
    5950       937207 :     *bitstart = *bitpos - bitoffset;
    5951              : 
    5952       937216 :   *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
    5953              : }
    5954              : 
    5955              : /* Returns true if BASE is a DECL that does not reside in memory and
    5956              :    has non-BLKmode.  DECL_RTL must not be a MEM; if
    5957              :    DECL_RTL was not set yet, return false.  */
    5958              : 
    5959              : bool
    5960      5550559 : non_mem_decl_p (tree base)
    5961              : {
    5962      5550559 :   if (!DECL_P (base)
    5963      5550161 :       || TREE_ADDRESSABLE (base)
    5964      8013056 :       || DECL_MODE (base) == BLKmode)
    5965              :     return false;
    5966              : 
    5967      1596946 :   if (!DECL_RTL_SET_P (base))
    5968              :     return false;
    5969              : 
    5970      1478106 :   return (!MEM_P (DECL_RTL (base)));
    5971              : }
    5972              : 
    5973              : /* Returns true if REF refers to an object that does not
    5974              :    reside in memory and has non-BLKmode.  */
    5975              : 
    5976              : bool
    5977     12132102 : mem_ref_refers_to_non_mem_p (tree ref)
    5978              : {
    5979     12132102 :   tree base;
    5980              : 
    5981     12132102 :   if (TREE_CODE (ref) == MEM_REF
    5982     12132102 :       || TREE_CODE (ref) == TARGET_MEM_REF)
    5983              :     {
    5984     10599600 :       tree addr = TREE_OPERAND (ref, 0);
    5985              : 
    5986     10599600 :       if (TREE_CODE (addr) != ADDR_EXPR)
    5987              :         return false;
    5988              : 
    5989      3992256 :       base = TREE_OPERAND (addr, 0);
    5990              :     }
    5991              :   else
    5992              :     base = ref;
    5993              : 
    5994      5524758 :   return non_mem_decl_p (base);
    5995              : }
    5996              : 
    5997              : /* Helper function of expand_assignment.  Check if storing field of
    5998              :    size BITSIZE at position BITPOS overlaps with the most significant
    5999              :    bit of TO_RTX, known to be SUBREG_PROMOTED_VAR_P.
    6000              :    Updating this field requires an explicit extension.  */
    6001              : static bool
    6002            0 : store_field_updates_msb_p (poly_int64 bitpos, poly_int64 bitsize, rtx to_rtx)
    6003              : {
    6004            0 :   return (BYTES_BIG_ENDIAN
    6005              :           ? maybe_le (bitpos, 0)
    6006            0 :           : maybe_ge (bitpos + bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))));
    6007              : }
    6008              : 
    6009              : /* Expand an assignment that stores the value of FROM into TO.  If NONTEMPORAL
    6010              :    is true, try generating a nontemporal store.  */
    6011              : 
    6012              : void
    6013     18702131 : expand_assignment (tree to, tree from, bool nontemporal)
    6014              : {
    6015     18702131 :   rtx to_rtx = 0;
    6016     18702131 :   rtx result;
    6017     18702131 :   machine_mode mode;
    6018     18702131 :   unsigned int align;
    6019     18702131 :   enum insn_code icode;
    6020              : 
    6021              :   /* Don't crash if the lhs of the assignment was erroneous.  */
    6022     18702131 :   if (TREE_CODE (to) == ERROR_MARK)
    6023              :     {
    6024            0 :       expand_normal (from);
    6025            0 :       return;
    6026              :     }
    6027              : 
    6028              :   /* Optimize away no-op moves without side-effects.  */
    6029     18702131 :   if (operand_equal_p (to, from, 0))
    6030              :     return;
    6031              : 
    6032              :   /* Handle misaligned stores.  */
    6033     18701976 :   mode = TYPE_MODE (TREE_TYPE (to));
    6034     18701976 :   if ((TREE_CODE (to) == MEM_REF
    6035     18701976 :        || TREE_CODE (to) == TARGET_MEM_REF
    6036     16466469 :        || DECL_P (to))
    6037      4097553 :       && mode != BLKmode
    6038      3629923 :       && !mem_ref_refers_to_non_mem_p (to)
    6039      6507384 :       && ((align = get_object_alignment (to))
    6040      3253692 :           < GET_MODE_ALIGNMENT (mode))
    6041     19138101 :       && (((icode = optab_handler (movmisalign_optab, mode))
    6042              :            != CODE_FOR_nothing)
    6043        97328 :           || targetm.slow_unaligned_access (mode, align)))
    6044              :     {
    6045       338797 :       rtx reg, mem;
    6046              : 
    6047       338797 :       reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
    6048              :       /* Handle PARALLEL.  */
    6049       338797 :       reg = maybe_emit_group_store (reg, TREE_TYPE (from));
    6050       338797 :       reg = force_not_mem (reg);
    6051       338797 :       mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6052       338797 :       if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
    6053            0 :         reg = flip_storage_order (mode, reg);
    6054              : 
    6055       338797 :       if (icode != CODE_FOR_nothing)
    6056              :         {
    6057       338797 :           class expand_operand ops[2];
    6058              : 
    6059       338797 :           create_fixed_operand (&ops[0], mem);
    6060       338797 :           create_input_operand (&ops[1], reg, mode);
    6061              :           /* The movmisalign<mode> pattern cannot fail, else the assignment
    6062              :              would silently be omitted.  */
    6063       338797 :           expand_insn (icode, 2, ops);
    6064              :         }
    6065              :       else
    6066            0 :         store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
    6067              :                          false, false);
    6068              :       return;
    6069              :     }
    6070              : 
    6071              :   /* Assignment of a structure component needs special treatment
    6072              :      if the structure component's rtx is not simply a MEM.
    6073              :      Assignment of an array element at a constant index, and assignment of
    6074              :      an array element in an unaligned packed structure field, has the same
    6075              :      problem.  Same for (partially) storing into a non-memory object.  */
    6076     18363179 :   if (handled_component_p (to)
    6077     13801137 :       || (TREE_CODE (to) == MEM_REF
    6078      1662873 :           && (REF_REVERSE_STORAGE_ORDER (to)
    6079      1662786 :               || mem_ref_refers_to_non_mem_p (to)))
    6080     13690872 :       || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
    6081              :     {
    6082      4794481 :       machine_mode mode1;
    6083      4794481 :       poly_int64 bitsize, bitpos;
    6084      4794481 :       poly_uint64 bitregion_start = 0;
    6085      4794481 :       poly_uint64 bitregion_end = 0;
    6086      4794481 :       tree offset;
    6087      4794481 :       int unsignedp, reversep, volatilep = 0;
    6088      4794481 :       tree tem;
    6089              : 
    6090      4794481 :       push_temp_slots ();
    6091      4794481 :       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
    6092              :                                  &unsignedp, &reversep, &volatilep);
    6093              : 
    6094              :       /* Make sure bitpos is not negative, it can wreak havoc later.  */
    6095      4794481 :       if (maybe_lt (bitpos, 0))
    6096              :         {
    6097          199 :           gcc_assert (offset == NULL_TREE);
    6098          199 :           offset = size_int (bits_to_bytes_round_down (bitpos));
    6099          199 :           bitpos = num_trailing_bits (bitpos);
    6100              :         }
    6101              : 
    6102      4794481 :       if (TREE_CODE (to) == COMPONENT_REF
    6103      4794481 :           && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
    6104        85514 :         get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
    6105              :       /* The C++ memory model naturally applies to byte-aligned fields.
    6106              :          However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
    6107              :          BITSIZE are not byte-aligned, there is no need to limit the range
    6108              :          we can access.  This can occur with packed structures in Ada.  */
    6109      4708967 :       else if (maybe_gt (bitsize, 0)
    6110      4708952 :                && multiple_p (bitsize, BITS_PER_UNIT)
    6111      9417652 :                && multiple_p (bitpos, BITS_PER_UNIT))
    6112              :         {
    6113      4708685 :           bitregion_start = bitpos;
    6114      4708685 :           bitregion_end = bitpos + bitsize - 1;
    6115              :         }
    6116              : 
    6117      4794481 :       to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6118              : 
    6119              :       /* If the field has a mode, we want to access it in the
    6120              :          field's mode, not the computed mode.
    6121              :          If a MEM has VOIDmode (external with incomplete type),
    6122              :          use BLKmode for it instead.  */
    6123      4794481 :       if (MEM_P (to_rtx))
    6124              :         {
    6125      4106534 :           if (mode1 != VOIDmode)
    6126      4039914 :             to_rtx = adjust_address (to_rtx, mode1, 0);
    6127        66620 :           else if (GET_MODE (to_rtx) == VOIDmode)
    6128            0 :             to_rtx = adjust_address (to_rtx, BLKmode, 0);
    6129              :         }
    6130              : 
    6131      4794481 :       rtx stemp = NULL_RTX, old_to_rtx = NULL_RTX;
    6132      4794481 :       if (offset != 0)
    6133              :         {
    6134       179673 :           machine_mode address_mode;
    6135       179673 :           rtx offset_rtx;
    6136              : 
    6137       179673 :           if (!MEM_P (to_rtx))
    6138              :             {
    6139              :               /* We can get constant negative offsets into arrays with broken
    6140              :                  user code.  Translate this to a trap instead of ICEing.  */
    6141            5 :               if (TREE_CODE (offset) == INTEGER_CST)
    6142              :                 {
    6143            2 :                   expand_builtin_trap ();
    6144            2 :                   to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
    6145              :                 }
    6146              :               /* Else spill for variable offset to the destination.  We expect
    6147              :                  to run into this only for hard registers.  */
    6148              :               else
    6149              :                 {
    6150            3 :                   gcc_assert (VAR_P (tem) && DECL_HARD_REGISTER (tem));
    6151            3 :                   stemp = assign_stack_temp (GET_MODE (to_rtx),
    6152            6 :                                              GET_MODE_SIZE (GET_MODE (to_rtx)));
    6153            3 :                   emit_move_insn (stemp, to_rtx);
    6154            3 :                   old_to_rtx = to_rtx;
    6155            3 :                   to_rtx = stemp;
    6156              :                 }
    6157              :             }
    6158              : 
    6159       179673 :           offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
    6160       179673 :           address_mode = get_address_mode (to_rtx);
    6161       179673 :           if (GET_MODE (offset_rtx) != address_mode)
    6162              :             {
    6163              :                 /* We cannot be sure that the RTL in offset_rtx is valid outside
    6164              :                    of a memory address context, so force it into a register
    6165              :                    before attempting to convert it to the desired mode.  */
    6166          224 :               offset_rtx = force_operand (offset_rtx, NULL_RTX);
    6167          224 :               offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
    6168              :             }
    6169              : 
    6170              :           /* If we have an expression in OFFSET_RTX and a non-zero
    6171              :              byte offset in BITPOS, adding the byte offset before the
    6172              :              OFFSET_RTX results in better intermediate code, which makes
    6173              :              later rtl optimization passes perform better.
    6174              : 
    6175              :              We prefer intermediate code like this:
    6176              : 
    6177              :              r124:DI=r123:DI+0x18
    6178              :              [r124:DI]=r121:DI
    6179              : 
    6180              :              ... instead of ...
    6181              : 
    6182              :              r124:DI=r123:DI+0x10
    6183              :              [r124:DI+0x8]=r121:DI
    6184              : 
    6185              :              This is only done for aligned data values, as these can
    6186              :              be expected to result in single move instructions.  */
    6187       179673 :           poly_int64 bytepos;
    6188       179673 :           if (mode1 != VOIDmode
    6189       179565 :               && maybe_ne (bitpos, 0)
    6190        47840 :               && maybe_gt (bitsize, 0)
    6191       227387 :               && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
    6192       227387 :               && multiple_p (bitpos, bitsize)
    6193        95428 :               && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
    6194       227387 :               && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
    6195              :             {
    6196        47465 :               to_rtx = adjust_address (to_rtx, mode1, bytepos);
    6197        47465 :               bitregion_start = 0;
    6198        47465 :               if (known_ge (bitregion_end, poly_uint64 (bitpos)))
    6199        47465 :                 bitregion_end -= bitpos;
    6200        47465 :               bitpos = 0;
    6201              :             }
    6202              : 
    6203       179673 :           to_rtx = offset_address (to_rtx, offset_rtx,
    6204              :                                    highest_pow2_factor_for_target (to,
    6205              :                                                                    offset));
    6206              :         }
    6207              : 
    6208              :       /* No action is needed if the target is not a memory and the field
    6209              :          lies completely outside that target.  This can occur if the source
    6210              :          code contains an out-of-bounds access to a small array.  */
    6211      4794481 :       if (!MEM_P (to_rtx)
    6212       687942 :           && GET_MODE (to_rtx) != BLKmode
    6213      5482423 :           && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
    6214              :         {
    6215            3 :           expand_normal (from);
    6216            3 :           result = NULL;
    6217              :         }
    6218              :       /* Handle expand_expr of a complex value returning a CONCAT.  */
    6219      4794478 :       else if (GET_CODE (to_rtx) == CONCAT)
    6220              :         {
    6221          122 :           machine_mode to_mode = GET_MODE (to_rtx);
    6222          122 :           gcc_checking_assert (COMPLEX_MODE_P (to_mode));
    6223          244 :           poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode);
    6224          122 :           unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
    6225          122 :           if (TYPE_MODE (TREE_TYPE (from)) == to_mode
    6226            0 :               && known_eq (bitpos, 0)
    6227          122 :               && known_eq (bitsize, mode_bitsize))
    6228            0 :             result = store_expr (from, to_rtx, false, nontemporal, reversep);
    6229          122 :           else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
    6230           70 :                    && known_eq (bitsize, inner_bitsize)
    6231          192 :                    && (known_eq (bitpos, 0)
    6232           31 :                        || known_eq (bitpos, inner_bitsize)))
    6233           70 :             result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
    6234              :                                  false, nontemporal, reversep);
    6235           52 :           else if (known_le (bitpos + bitsize, inner_bitsize))
    6236            5 :             result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
    6237              :                                   bitregion_start, bitregion_end,
    6238              :                                   mode1, from, get_alias_set (to),
    6239              :                                   nontemporal, reversep);
    6240           47 :           else if (known_ge (bitpos, inner_bitsize))
    6241            3 :             result = store_field (XEXP (to_rtx, 1), bitsize,
    6242              :                                   bitpos - inner_bitsize,
    6243              :                                   bitregion_start, bitregion_end,
    6244              :                                   mode1, from, get_alias_set (to),
    6245              :                                   nontemporal, reversep);
    6246           44 :           else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
    6247              :             {
    6248           37 :               result = expand_normal (from);
    6249           37 :               if (GET_CODE (result) == CONCAT)
    6250              :                 {
    6251            0 :                   to_mode = GET_MODE_INNER (to_mode);
    6252            0 :                   machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
    6253            0 :                   rtx from_real
    6254            0 :                     = force_subreg (to_mode, XEXP (result, 0), from_mode, 0);
    6255            0 :                   rtx from_imag
    6256            0 :                     = force_subreg (to_mode, XEXP (result, 1), from_mode, 0);
    6257            0 :                   if (!from_real || !from_imag)
    6258            0 :                     goto concat_store_slow;
    6259            0 :                   emit_move_insn (XEXP (to_rtx, 0), from_real);
    6260            0 :                   emit_move_insn (XEXP (to_rtx, 1), from_imag);
    6261              :                 }
    6262              :               else
    6263              :                 {
    6264           37 :                   machine_mode from_mode
    6265           37 :                     = GET_MODE (result) == VOIDmode
    6266           37 :                       ? TYPE_MODE (TREE_TYPE (from))
    6267           37 :                       : GET_MODE (result);
    6268           37 :                   rtx from_rtx;
    6269           37 :                   if (MEM_P (result))
    6270            1 :                     from_rtx = change_address (result, to_mode, NULL_RTX);
    6271              :                   else
    6272           36 :                     from_rtx = force_subreg (to_mode, result, from_mode, 0);
    6273           37 :                   if (from_rtx)
    6274              :                     {
    6275           37 :                       emit_move_insn (XEXP (to_rtx, 0),
    6276              :                                       read_complex_part (from_rtx, false));
    6277           37 :                       emit_move_insn (XEXP (to_rtx, 1),
    6278              :                                       read_complex_part (from_rtx, true));
    6279              :                     }
    6280              :                   else
    6281              :                     {
    6282            0 :                       to_mode = GET_MODE_INNER (to_mode);
    6283            0 :                       rtx from_real
    6284            0 :                         = force_subreg (to_mode, result, from_mode, 0);
    6285            0 :                       rtx from_imag
    6286            0 :                         = force_subreg (to_mode, result, from_mode,
    6287            0 :                                         GET_MODE_SIZE (to_mode));
    6288            0 :                       if (!from_real || !from_imag)
    6289            0 :                         goto concat_store_slow;
    6290            0 :                       emit_move_insn (XEXP (to_rtx, 0), from_real);
    6291            0 :                       emit_move_insn (XEXP (to_rtx, 1), from_imag);
    6292              :                     }
    6293              :                 }
    6294              :             }
    6295              :           else
    6296              :             {
    6297            7 :             concat_store_slow:;
    6298            7 :               rtx temp = assign_stack_temp (GET_MODE (to_rtx),
    6299           14 :                                             GET_MODE_SIZE (GET_MODE (to_rtx)));
    6300            7 :               write_complex_part (temp, XEXP (to_rtx, 0), false, true);
    6301            7 :               write_complex_part (temp, XEXP (to_rtx, 1), true, false);
    6302            7 :               result = store_field (temp, bitsize, bitpos,
    6303              :                                     bitregion_start, bitregion_end,
    6304              :                                     mode1, from, get_alias_set (to),
    6305              :                                     nontemporal, reversep);
    6306            7 :               emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
    6307            7 :               emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
    6308              :             }
    6309              :         }
    6310              :       /* For calls to functions returning variable length structures, if TO_RTX
    6311              :          is not a MEM, go through a MEM because we must not create temporaries
    6312              :          of the VLA type.  */
    6313      4794356 :       else if (!MEM_P (to_rtx)
    6314       687817 :                && TREE_CODE (from) == CALL_EXPR
    6315          236 :                && COMPLETE_TYPE_P (TREE_TYPE (from))
    6316      4794592 :                && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
    6317              :         {
    6318            6 :           rtx temp = assign_stack_temp (GET_MODE (to_rtx),
    6319           12 :                                         GET_MODE_SIZE (GET_MODE (to_rtx)));
    6320            6 :           result = store_field (temp, bitsize, bitpos, bitregion_start,
    6321              :                                 bitregion_end, mode1, from, get_alias_set (to),
    6322              :                                 nontemporal, reversep);
    6323            6 :           emit_move_insn (to_rtx, temp);
    6324              :         }
    6325              :       else
    6326              :         {
    6327      4794350 :           if (MEM_P (to_rtx))
    6328              :             {
    6329              :               /* If the field is at offset zero, we could have been given the
    6330              :                  DECL_RTX of the parent struct.  Don't munge it.  */
    6331      4106539 :               to_rtx = shallow_copy_rtx (to_rtx);
    6332      4106539 :               set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos, true);
    6333      4106539 :               if (volatilep)
    6334         8738 :                 MEM_VOLATILE_P (to_rtx) = 1;
    6335              :             }
    6336              : 
    6337      4794350 :           gcc_checking_assert (known_ge (bitpos, 0));
    6338      9588700 :           if (optimize_bitfield_assignment_op (bitsize, bitpos,
    6339              :                                                bitregion_start, bitregion_end,
    6340              :                                                mode1, to_rtx, to, from,
    6341              :                                                reversep))
    6342              :             result = NULL;
    6343      4794184 :           else if (SUBREG_P (to_rtx)
    6344      4794184 :                    && SUBREG_PROMOTED_VAR_P (to_rtx))
    6345              :             {
    6346              :               /* If to_rtx is a promoted subreg, we need to zero or sign
    6347              :                  extend the value afterwards.  */
    6348            0 :               if (TREE_CODE (to) == MEM_REF
    6349            0 :                   && TYPE_MODE (TREE_TYPE (from)) != BLKmode
    6350            0 :                   && !REF_REVERSE_STORAGE_ORDER (to)
    6351            0 :                   && known_eq (bitpos, 0)
    6352            0 :                   && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
    6353            0 :                 result = store_expr (from, to_rtx, 0, nontemporal, false);
    6354              :               /* Check if the field overlaps the MSB, requiring extension.  */
    6355            0 :               else if (store_field_updates_msb_p (bitpos, bitsize, to_rtx))
    6356              :                 {
    6357            0 :                   scalar_int_mode imode = subreg_unpromoted_mode (to_rtx);
    6358            0 :                   scalar_int_mode omode = subreg_promoted_mode (to_rtx);
    6359            0 :                   rtx to_rtx1 = lowpart_subreg (imode, SUBREG_REG (to_rtx),
    6360              :                                                 omode);
    6361            0 :                   result = store_field (to_rtx1, bitsize, bitpos,
    6362              :                                         bitregion_start, bitregion_end,
    6363              :                                         mode1, from, get_alias_set (to),
    6364              :                                         nontemporal, reversep);
    6365              :                   /* If the target usually keeps IMODE appropriately
    6366              :                      extended in OMODE it's unsafe to refer to it using
    6367              :                      a SUBREG whilst this invariant doesn't hold.  */
    6368            0 :                   if (targetm.mode_rep_extended (imode, omode) != UNKNOWN)
    6369            0 :                     to_rtx1 = simplify_gen_unary (TRUNCATE, imode,
    6370              :                                                   SUBREG_REG (to_rtx), omode);
    6371            0 :                   convert_move (SUBREG_REG (to_rtx), to_rtx1,
    6372            0 :                                 SUBREG_PROMOTED_SIGN (to_rtx));
    6373              :                 }
    6374              :               else
    6375            0 :                 result = store_field (to_rtx, bitsize, bitpos,
    6376              :                                       bitregion_start, bitregion_end,
    6377              :                                       mode1, from, get_alias_set (to),
    6378              :                                       nontemporal, reversep);
    6379              :             }
    6380              :           else
    6381      4794184 :             result = store_field (to_rtx, bitsize, bitpos,
    6382              :                                   bitregion_start, bitregion_end,
    6383              :                                   mode1, from, get_alias_set (to),
    6384              :                                   nontemporal, reversep);
    6385              :           /* Move the temporary storage back to the non-MEM_P.  */
    6386      4794350 :           if (stemp)
    6387            3 :             emit_move_insn (old_to_rtx, stemp);
    6388              :         }
    6389              : 
    6390      4794481 :       if (result)
    6391       829816 :         preserve_temp_slots (result);
    6392      4794481 :       pop_temp_slots ();
    6393      4794481 :       return;
    6394              :     }
    6395              : 
    6396              :   /* If the rhs is a function call and its value is not an aggregate,
    6397              :      call the function before we start to compute the lhs.
    6398              :      This is needed for correct code for cases such as
    6399              :      val = setjmp (buf) on machines where reference to val
    6400              :      requires loading up part of an address in a separate insn.
    6401              : 
    6402              :      Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
    6403              :      since it might be a promoted variable where the zero- or sign- extension
    6404              :      needs to be done.  Handling this in the normal way is safe because no
    6405              :      computation is done before the call.  The same is true for SSA names.  */
    6406      2359130 :   if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
    6407      2159847 :       && COMPLETE_TYPE_P (TREE_TYPE (from))
    6408      2159847 :       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
    6409     15728545 :       && ! (((VAR_P (to)
    6410              :               || TREE_CODE (to) == PARM_DECL
    6411              :               || TREE_CODE (to) == RESULT_DECL)
    6412       122333 :              && REG_P (DECL_RTL (to)))
    6413      2047728 :             || TREE_CODE (to) == SSA_NAME))
    6414              :     {
    6415        10547 :       rtx value;
    6416              : 
    6417        10547 :       push_temp_slots ();
    6418        10547 :       value = expand_normal (from);
    6419              : 
    6420        10547 :       if (to_rtx == 0)
    6421        10547 :         to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6422              : 
    6423              :       /* Handle calls that return values in multiple non-contiguous locations.
    6424              :          The Irix 6 ABI has examples of this.  */
    6425        10547 :       if (GET_CODE (to_rtx) == PARALLEL)
    6426              :         {
    6427            0 :           if (GET_CODE (value) == PARALLEL)
    6428            0 :             emit_group_move (to_rtx, value);
    6429              :           else
    6430            0 :             emit_group_load (to_rtx, value, TREE_TYPE (from),
    6431            0 :                              int_size_in_bytes (TREE_TYPE (from)));
    6432              :         }
    6433        10547 :       else if (GET_CODE (value) == PARALLEL)
    6434         1957 :         emit_group_store (to_rtx, value, TREE_TYPE (from),
    6435         1957 :                           int_size_in_bytes (TREE_TYPE (from)));
    6436         8590 :       else if (GET_MODE (to_rtx) == BLKmode)
    6437              :         {
    6438              :           /* Handle calls that return BLKmode values in registers.  */
    6439          254 :           if (REG_P (value))
    6440          254 :             copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
    6441              :           else
    6442            0 :             emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
    6443              :         }
    6444              :       else
    6445              :         {
    6446         8336 :           if (POINTER_TYPE_P (TREE_TYPE (to)))
    6447            0 :             value = convert_memory_address_addr_space
    6448            0 :               (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
    6449            0 :                TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
    6450              : 
    6451         8336 :           emit_move_insn (to_rtx, value);
    6452              :         }
    6453              : 
    6454        10547 :       preserve_temp_slots (to_rtx);
    6455        10547 :       pop_temp_slots ();
    6456        10547 :       return;
    6457              :     }
    6458              : 
    6459              :   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.  */
    6460     13558151 :   to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
    6461              : 
    6462              :   /* Don't move directly into a return register.  */
    6463     13558151 :   if (TREE_CODE (to) == RESULT_DECL
    6464        29314 :       && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
    6465              :     {
    6466            0 :       rtx temp;
    6467              : 
    6468            0 :       push_temp_slots ();
    6469              : 
    6470              :       /* If the source is itself a return value, it still is in a pseudo at
    6471              :          this point so we can move it back to the return register directly.  */
    6472            0 :       if (REG_P (to_rtx)
    6473            0 :           && TYPE_MODE (TREE_TYPE (from)) == BLKmode
    6474            0 :           && TREE_CODE (from) != CALL_EXPR)
    6475            0 :         temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
    6476              :       else
    6477            0 :         temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
    6478              : 
    6479              :       /* Handle calls that return values in multiple non-contiguous locations.
    6480              :          The Irix 6 ABI has examples of this.  */
    6481            0 :       if (GET_CODE (to_rtx) == PARALLEL)
    6482              :         {
    6483            0 :           if (GET_CODE (temp) == PARALLEL)
    6484            0 :             emit_group_move (to_rtx, temp);
    6485              :           else
    6486            0 :             emit_group_load (to_rtx, temp, TREE_TYPE (from),
    6487            0 :                              int_size_in_bytes (TREE_TYPE (from)));
    6488              :         }
    6489            0 :       else if (temp)
    6490            0 :         emit_move_insn (to_rtx, temp);
    6491              : 
    6492            0 :       preserve_temp_slots (to_rtx);
    6493            0 :       pop_temp_slots ();
    6494            0 :       return;
    6495              :     }
    6496              : 
    6497              :   /* In case we are returning the contents of an object which overlaps
    6498              :      the place the value is being stored, use a safe function when copying
    6499              :      a value through a pointer into a structure value return block.  */
    6500     13558151 :   if (TREE_CODE (to) == RESULT_DECL
    6501        29314 :       && TREE_CODE (from) == INDIRECT_REF
    6502            0 :       && ADDR_SPACE_GENERIC_P
    6503              :            (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
    6504            0 :       && refs_may_alias_p (to, from)
    6505            0 :       && cfun->returns_struct
    6506     13558151 :       && !cfun->returns_pcc_struct)
    6507              :     {
    6508            0 :       rtx from_rtx, size;
    6509              : 
    6510            0 :       push_temp_slots ();
    6511            0 :       size = expr_size (from);
    6512            0 :       from_rtx = expand_normal (from);
    6513              : 
    6514            0 :       emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
    6515              : 
    6516            0 :       preserve_temp_slots (to_rtx);
    6517            0 :       pop_temp_slots ();
    6518            0 :       return;
    6519              :     }
    6520              : 
    6521              :   /* Compute FROM and store the value in the rtx we got.  */
    6522              : 
    6523     13558151 :   push_temp_slots ();
    6524     13558151 :   result = store_expr (from, to_rtx, 0, nontemporal, false);
    6525     13558149 :   preserve_temp_slots (result);
    6526     13558149 :   pop_temp_slots ();
    6527     13558149 :   return;
    6528              : }
    6529              : 
    6530              : /* Emits nontemporal store insn that moves FROM to TO.  Returns true if this
    6531              :    succeeded, false otherwise.  */
    6532              : 
    6533              : bool
    6534           17 : emit_storent_insn (rtx to, rtx from)
    6535              : {
    6536           17 :   class expand_operand ops[2];
    6537           17 :   machine_mode mode = GET_MODE (to);
    6538           17 :   enum insn_code code = optab_handler (storent_optab, mode);
    6539              : 
    6540           17 :   if (code == CODE_FOR_nothing)
    6541              :     return false;
    6542              : 
    6543           17 :   create_fixed_operand (&ops[0], to);
    6544           17 :   create_input_operand (&ops[1], from, mode);
    6545           17 :   return maybe_expand_insn (code, 2, ops);
    6546              : }
    6547              : 
    6548              : /* Helper function for store_expr storing of STRING_CST.  */
    6549              : 
    6550              : static rtx
    6551        80510 : string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
    6552              :                      fixed_size_mode mode)
    6553              : {
    6554        80510 :   tree str = (tree) data;
    6555              : 
    6556        80510 :   gcc_assert (offset >= 0);
    6557        80510 :   if (offset >= TREE_STRING_LENGTH (str))
    6558         3352 :     return const0_rtx;
    6559              : 
    6560        77158 :   if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
    6561        77158 :       > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
    6562              :     {
    6563         2486 :       char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
    6564         2486 :       size_t l = TREE_STRING_LENGTH (str) - offset;
    6565         2486 :       memcpy (p, TREE_STRING_POINTER (str) + offset, l);
    6566         2486 :       memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
    6567         2486 :       return c_readstr (p, mode, false);
    6568              :     }
    6569              : 
    6570        74672 :   return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
    6571              : }
    6572              : 
    6573              : /* Helper function for store_expr storing of RAW_DATA_CST.  */
    6574              : 
    6575              : static rtx
    6576           36 : raw_data_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
    6577              :                        fixed_size_mode mode)
    6578              : {
    6579           36 :   tree cst = (tree) data;
    6580              : 
    6581           36 :   gcc_assert (offset >= 0);
    6582           36 :   if (offset >= RAW_DATA_LENGTH (cst))
    6583            0 :     return const0_rtx;
    6584              : 
    6585           36 :   if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
    6586           36 :       > (unsigned HOST_WIDE_INT) RAW_DATA_LENGTH (cst))
    6587              :     {
    6588            0 :       char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
    6589            0 :       size_t l = RAW_DATA_LENGTH (cst) - offset;
    6590            0 :       memcpy (p, RAW_DATA_POINTER (cst) + offset, l);
    6591            0 :       memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
    6592            0 :       return c_readstr (p, mode, false);
    6593              :     }
    6594              : 
    6595           36 :   return c_readstr (RAW_DATA_POINTER (cst) + offset, mode, false);
    6596              : }
    6597              : 
    6598              : /* Generate code for computing expression EXP,
    6599              :    and storing the value into TARGET.
    6600              : 
    6601              :    If the mode is BLKmode then we may return TARGET itself.
    6602              :    It turns out that in BLKmode it doesn't cause a problem.
    6603              :    because C has no operators that could combine two different
    6604              :    assignments into the same BLKmode object with different values
    6605              :    with no sequence point.  Will other languages need this to
    6606              :    be more thorough?
    6607              : 
    6608              :    If CALL_PARAM_P is nonzero, this is a store into a call param on the
    6609              :    stack, and block moves may need to be treated specially.
    6610              : 
    6611              :    If NONTEMPORAL is true, try using a nontemporal store instruction.
    6612              : 
    6613              :    If REVERSE is true, the store is to be done in reverse order.  */
    6614              : 
    6615              : rtx
    6616     17563703 : store_expr (tree exp, rtx target, int call_param_p,
    6617              :             bool nontemporal, bool reverse)
    6618              : {
    6619     17563703 :   rtx temp;
    6620     17563703 :   rtx alt_rtl = NULL_RTX;
    6621     17563703 :   location_t loc = curr_insn_location ();
    6622     17563703 :   bool shortened_string_cst = false;
    6623              : 
    6624     17563703 :   if (VOID_TYPE_P (TREE_TYPE (exp)))
    6625              :     {
    6626              :       /* C++ can generate ?: expressions with a throw expression in one
    6627              :          branch and an rvalue in the other. Here, we resolve attempts to
    6628              :          store the throw expression's nonexistent result.  */
    6629            0 :       gcc_assert (!call_param_p);
    6630            0 :       expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
    6631            0 :       return NULL_RTX;
    6632              :     }
    6633     17563703 :   if (TREE_CODE (exp) == COMPOUND_EXPR)
    6634              :     {
    6635              :       /* Perform first part of compound expression, then assign from second
    6636              :          part.  */
    6637            0 :       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
    6638              :                    call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
    6639            0 :       return store_expr (TREE_OPERAND (exp, 1), target,
    6640            0 :                                      call_param_p, nontemporal, reverse);
    6641              :     }
    6642     17563703 :   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
    6643              :     {
    6644              :       /* For conditional expression, get safe form of the target.  Then
    6645              :          test the condition, doing the appropriate assignment on either
    6646              :          side.  This avoids the creation of unnecessary temporaries.
    6647              :          For non-BLKmode, it is more efficient not to do this.  */
    6648              : 
    6649            0 :       rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
    6650              : 
    6651            0 :       do_pending_stack_adjust ();
    6652            0 :       NO_DEFER_POP;
    6653            0 :       jumpifnot (TREE_OPERAND (exp, 0), lab1,
    6654              :                  profile_probability::uninitialized ());
    6655            0 :       store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
    6656              :                   nontemporal, reverse);
    6657            0 :       emit_jump_insn (targetm.gen_jump (lab2));
    6658            0 :       emit_barrier ();
    6659            0 :       emit_label (lab1);
    6660            0 :       store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
    6661              :                   nontemporal, reverse);
    6662            0 :       emit_label (lab2);
    6663            0 :       OK_DEFER_POP;
    6664              : 
    6665            0 :       return NULL_RTX;
    6666              :     }
    6667     17563703 :   else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
    6668              :     /* If this is a scalar in a register that is stored in a wider mode
    6669              :        than the declared mode, compute the result into its declared mode
    6670              :        and then convert to the wider mode.  Our value is the computed
    6671              :        expression.  */
    6672              :     {
    6673            7 :       rtx inner_target = 0;
    6674            7 :       scalar_int_mode outer_mode = subreg_unpromoted_mode (target);
    6675            7 :       scalar_int_mode inner_mode = subreg_promoted_mode (target);
    6676              : 
    6677              :       /* We can do the conversion inside EXP, which will often result
    6678              :          in some optimizations.  Do the conversion in two steps: first
    6679              :          change the signedness, if needed, then the extend.  But don't
    6680              :          do this if the type of EXP is a subtype of something else
    6681              :          since then the conversion might involve more than just
    6682              :          converting modes.  */
    6683           14 :       if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
    6684            0 :           && TREE_TYPE (TREE_TYPE (exp)) == 0
    6685            7 :           && GET_MODE_PRECISION (outer_mode)
    6686            0 :              == TYPE_PRECISION (TREE_TYPE (exp)))
    6687              :         {
    6688            0 :           if (!SUBREG_CHECK_PROMOTED_SIGN (target,
    6689              :                                           TYPE_UNSIGNED (TREE_TYPE (exp))))
    6690              :             {
    6691              :               /* Some types, e.g. Fortran's logical*4, won't have a signed
    6692              :                  version, so use the mode instead.  */
    6693            0 :               tree ntype
    6694              :                 = (signed_or_unsigned_type_for
    6695            0 :                    (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
    6696            0 :               if (ntype == NULL)
    6697            0 :                 ntype = lang_hooks.types.type_for_mode
    6698            0 :                   (TYPE_MODE (TREE_TYPE (exp)),
    6699            0 :                    SUBREG_PROMOTED_SIGN (target));
    6700              : 
    6701            0 :               exp = fold_convert_loc (loc, ntype, exp);
    6702              :             }
    6703              : 
    6704            0 :           exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
    6705            0 :                                   (inner_mode, SUBREG_PROMOTED_SIGN (target)),
    6706              :                                   exp);
    6707              : 
    6708            0 :           inner_target = SUBREG_REG (target);
    6709              :         }
    6710              : 
    6711            7 :       temp = expand_expr (exp, inner_target, VOIDmode,
    6712              :                           call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
    6713              : 
    6714              : 
    6715              :       /* If TEMP is a VOIDmode constant, use convert_modes to make
    6716              :          sure that we properly convert it.  */
    6717            7 :       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
    6718              :         {
    6719            0 :           temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
    6720            0 :                                 temp, SUBREG_PROMOTED_SIGN (target));
    6721            0 :           temp = convert_modes (inner_mode, outer_mode, temp,
    6722            0 :                                 SUBREG_PROMOTED_SIGN (target));
    6723            0 :         }
    6724            7 :       else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
    6725            0 :         temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
    6726            0 :                               temp, SUBREG_PROMOTED_SIGN (target));
    6727              : 
    6728           21 :       convert_move (SUBREG_REG (target), temp,
    6729            7 :                     SUBREG_PROMOTED_SIGN (target));
    6730              : 
    6731            7 :       return NULL_RTX;
    6732              :     }
    6733     17563696 :   else if ((TREE_CODE (exp) == STRING_CST
    6734     17556399 :             || (TREE_CODE (exp) == MEM_REF
    6735      1362091 :                 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
    6736       443379 :                 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    6737              :                    == STRING_CST
    6738         6604 :                 && integer_zerop (TREE_OPERAND (exp, 1))))
    6739        13901 :            && !nontemporal && !call_param_p
    6740     17577597 :            && MEM_P (target))
    6741              :     {
    6742              :       /* Optimize initialization of an array with a STRING_CST.  */
    6743        13883 :       HOST_WIDE_INT exp_len, str_copy_len;
    6744        13883 :       rtx dest_mem;
    6745        13883 :       tree str = TREE_CODE (exp) == STRING_CST
    6746        13883 :                  ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    6747              : 
    6748        13883 :       exp_len = int_expr_size (exp);
    6749        13883 :       if (exp_len <= 0)
    6750            0 :         goto normal_expr;
    6751              : 
    6752        13883 :       if (TREE_STRING_LENGTH (str) <= 0)
    6753            0 :         goto normal_expr;
    6754              : 
    6755        27766 :       if (can_store_by_pieces (exp_len, string_cst_read_str, (void *) str,
    6756        13883 :                                MEM_ALIGN (target), false))
    6757              :         {
    6758        13686 :           store_by_pieces (target, exp_len, string_cst_read_str, (void *) str,
    6759        13686 :                            MEM_ALIGN (target), false, RETURN_BEGIN);
    6760        13686 :           return NULL_RTX;
    6761              :         }
    6762              : 
    6763          197 :       str_copy_len = TREE_STRING_LENGTH (str);
    6764              : 
    6765              :       /* Trailing NUL bytes in EXP will be handled by the call to
    6766              :          clear_storage, which is more efficient than copying them from
    6767              :          the STRING_CST, so trim those from STR_COPY_LEN.  */
    6768          333 :       while (str_copy_len)
    6769              :         {
    6770          280 :           if (TREE_STRING_POINTER (str)[str_copy_len - 1])
    6771              :             break;
    6772          136 :           str_copy_len--;
    6773              :         }
    6774              : 
    6775          197 :       if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
    6776              :         {
    6777          197 :           str_copy_len += STORE_MAX_PIECES - 1;
    6778          197 :           str_copy_len &= ~(STORE_MAX_PIECES - 1);
    6779              :         }
    6780          197 :       if (str_copy_len >= exp_len)
    6781          136 :         goto normal_expr;
    6782              : 
    6783          122 :       if (!can_store_by_pieces (str_copy_len, string_cst_read_str,
    6784           61 :                                 (void *) str, MEM_ALIGN (target), false))
    6785            2 :         goto normal_expr;
    6786              : 
    6787           59 :       dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
    6788           59 :                                   (void *) str, MEM_ALIGN (target), false,
    6789              :                                   RETURN_END);
    6790           59 :       clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
    6791           59 :                                        exp_len - str_copy_len),
    6792              :                      GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
    6793           59 :       return NULL_RTX;
    6794              :     }
    6795              :   else
    6796              :     {
    6797     17549951 :       rtx tmp_target;
    6798              : 
    6799     17549951 :   normal_expr:
    6800              :       /* If we want to use a nontemporal or a reverse order store, force the
    6801              :          value into a register first.  */
    6802     17549951 :       tmp_target = nontemporal || reverse ? NULL_RTX : target;
    6803     17549951 :       tree rexp = exp;
    6804     17549951 :       if (TREE_CODE (exp) == STRING_CST
    6805           20 :           && tmp_target == target
    6806           20 :           && GET_MODE (target) == BLKmode
    6807     17549971 :           && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
    6808              :         {
    6809           20 :           rtx size = expr_size (exp);
    6810           20 :           if (CONST_INT_P (size)
    6811           20 :               && size != const0_rtx
    6812           40 :               && (UINTVAL (size)
    6813           20 :                   > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
    6814              :             {
    6815              :               /* If the STRING_CST has much larger array type than
    6816              :                  TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
    6817              :                  it into the rodata section as the code later on will use
    6818              :                  memset zero for the remainder anyway.  See PR95052.  */
    6819            2 :               tmp_target = NULL_RTX;
    6820            2 :               rexp = copy_node (exp);
    6821            2 :               tree index
    6822            2 :                 = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
    6823            2 :               TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
    6824              :                                                    index);
    6825            2 :               shortened_string_cst = true;
    6826              :             }
    6827              :         }
    6828     35099902 :       temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
    6829              :                                (call_param_p
    6830              :                                 ? EXPAND_STACK_PARM : EXPAND_NORMAL),
    6831              :                                &alt_rtl, false);
    6832     17549949 :       if (shortened_string_cst)
    6833              :         {
    6834            2 :           gcc_assert (MEM_P (temp));
    6835            2 :           temp = change_address (temp, BLKmode, NULL_RTX);
    6836              :         }
    6837              :     }
    6838              : 
    6839              :   /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
    6840              :      the same as that of TARGET, adjust the constant.  This is needed, for
    6841              :      example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
    6842              :      only a word-sized value.  */
    6843      3617337 :   if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
    6844      2617881 :       && TREE_CODE (exp) != ERROR_MARK
    6845     20167830 :       && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
    6846              :     {
    6847            0 :       gcc_assert (!shortened_string_cst);
    6848            0 :       if (GET_MODE_CLASS (GET_MODE (target))
    6849            0 :           != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
    6850            0 :           && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
    6851              :                        GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
    6852              :         {
    6853            0 :           rtx t = simplify_gen_subreg (GET_MODE (target), temp,
    6854            0 :                                        TYPE_MODE (TREE_TYPE (exp)), 0);
    6855            0 :           if (t)
    6856            0 :             temp = t;
    6857              :         }
    6858            0 :       if (GET_MODE (temp) == VOIDmode)
    6859            0 :         temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
    6860            0 :                               temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
    6861              :     }
    6862              : 
    6863              :   /* If value was not generated in the target, store it there.
    6864              :      Convert the value to TARGET's type first if necessary and emit the
    6865              :      pending incrementations that have been queued when expanding EXP.
    6866              :      Note that we cannot emit the whole queue blindly because this will
    6867              :      effectively disable the POST_INC optimization later.
    6868              : 
    6869              :      If TEMP and TARGET compare equal according to rtx_equal_p, but
    6870              :      one or both of them are volatile memory refs, we have to distinguish
    6871              :      two cases:
    6872              :      - expand_expr has used TARGET.  In this case, we must not generate
    6873              :        another copy.  This can be detected by TARGET being equal according
    6874              :        to == .
    6875              :      - expand_expr has not used TARGET - that means that the source just
    6876              :        happens to have the same RTX form.  Since temp will have been created
    6877              :        by expand_expr, it will compare unequal according to == .
    6878              :        We must generate a copy in this case, to reach the correct number
    6879              :        of volatile memory references.  */
    6880              : 
    6881     17549949 :   if ((! rtx_equal_p (temp, target)
    6882      3129417 :        || (temp != target && (side_effects_p (temp)
    6883        46987 :                               || side_effects_p (target)
    6884        46987 :                               || (MEM_P (temp)
    6885        46576 :                                   && !mems_same_for_tbaa_p (temp, target)))))
    6886     14420536 :       && TREE_CODE (exp) != ERROR_MARK
    6887              :       /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
    6888              :          but TARGET is not valid memory reference, TEMP will differ
    6889              :          from TARGET although it is really the same location.  */
    6890     14420536 :       && !(alt_rtl
    6891      1980235 :            && rtx_equal_p (alt_rtl, target)
    6892            1 :            && !side_effects_p (alt_rtl)
    6893            0 :            && !side_effects_p (target))
    6894              :       /* If there's nothing to copy, don't bother.  Don't call
    6895              :          expr_size unless necessary, because some front-ends (C++)
    6896              :          expr_size-hook must not be given objects that are not
    6897              :          supposed to be bit-copied or bit-initialized.  */
    6898     31970485 :       && expr_size (exp) != const0_rtx)
    6899              :     {
    6900     14420536 :       if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
    6901              :         {
    6902         1378 :           gcc_assert (!shortened_string_cst);
    6903         1378 :           if (GET_MODE (target) == BLKmode)
    6904              :             {
    6905              :               /* Handle calls that return BLKmode values in registers.  */
    6906            2 :               if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
    6907            2 :                 copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
    6908              :               else
    6909            0 :                 store_bit_field (target,
    6910            0 :                                  rtx_to_poly_int64 (expr_size (exp))
    6911            0 :                                  * BITS_PER_UNIT,
    6912              :                                  0, 0, 0, GET_MODE (temp), temp, reverse,
    6913              :                                  false);
    6914              :             }
    6915              :           else
    6916         1376 :             convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
    6917              :         }
    6918              : 
    6919     14419158 :       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
    6920              :         {
    6921              :           /* Handle copying a string constant into an array.  The string
    6922              :              constant may be shorter than the array.  So copy just the string's
    6923              :              actual length, and clear the rest.  First get the size of the data
    6924              :              type of the string, which is actually the size of the target.  */
    6925           20 :           rtx size = expr_size (exp);
    6926              : 
    6927           20 :           if (CONST_INT_P (size)
    6928           20 :               && INTVAL (size) < TREE_STRING_LENGTH (exp))
    6929            0 :             emit_block_move (target, temp, size,
    6930              :                              (call_param_p
    6931              :                               ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    6932              :           else
    6933              :             {
    6934           20 :               machine_mode pointer_mode
    6935           20 :                 = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
    6936           20 :               machine_mode address_mode = get_address_mode (target);
    6937              : 
    6938              :               /* Compute the size of the data to copy from the string.  */
    6939           20 :               tree copy_size
    6940           20 :                 = size_binop_loc (loc, MIN_EXPR,
    6941              :                                   make_tree (sizetype, size),
    6942           20 :                                   size_int (TREE_STRING_LENGTH (exp)));
    6943           20 :               rtx copy_size_rtx
    6944           20 :                 = expand_expr (copy_size, NULL_RTX, VOIDmode,
    6945              :                                (call_param_p
    6946              :                                 ? EXPAND_STACK_PARM : EXPAND_NORMAL));
    6947           20 :               rtx_code_label *label = 0;
    6948              : 
    6949              :               /* Copy that much.  */
    6950           60 :               copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
    6951           20 :                                                TYPE_UNSIGNED (sizetype));
    6952           40 :               emit_block_move (target, temp, copy_size_rtx,
    6953              :                                (call_param_p
    6954              :                                 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    6955              : 
    6956              :               /* Figure out how much is left in TARGET that we have to clear.
    6957              :                  Do all calculations in pointer_mode.  */
    6958           20 :               poly_int64 const_copy_size;
    6959           20 :               if (poly_int_rtx_p (copy_size_rtx, &const_copy_size))
    6960              :                 {
    6961           20 :                   size = plus_constant (address_mode, size, -const_copy_size);
    6962           20 :                   target = adjust_address (target, BLKmode, const_copy_size);
    6963              :                 }
    6964              :               else
    6965              :                 {
    6966            0 :                   size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
    6967              :                                        copy_size_rtx, NULL_RTX, 0,
    6968              :                                        OPTAB_LIB_WIDEN);
    6969              : 
    6970            0 :                   if (GET_MODE (copy_size_rtx) != address_mode)
    6971            0 :                     copy_size_rtx = convert_to_mode (address_mode,
    6972              :                                                      copy_size_rtx,
    6973            0 :                                                      TYPE_UNSIGNED (sizetype));
    6974              : 
    6975            0 :                   target = offset_address (target, copy_size_rtx,
    6976              :                                            highest_pow2_factor (copy_size));
    6977            0 :                   label = gen_label_rtx ();
    6978            0 :                   emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
    6979            0 :                                            GET_MODE (size), 0, label);
    6980              :                 }
    6981              : 
    6982           20 :               if (size != const0_rtx)
    6983            2 :                 clear_storage (target, size, BLOCK_OP_NORMAL);
    6984              : 
    6985           20 :               if (label)
    6986            0 :                 emit_label (label);
    6987              :             }
    6988              :         }
    6989     14419138 :       else if (shortened_string_cst)
    6990            0 :         gcc_unreachable ();
    6991              :       /* Handle calls that return values in multiple non-contiguous locations.
    6992              :          The Irix 6 ABI has examples of this.  */
    6993     14419138 :       else if (GET_CODE (target) == PARALLEL)
    6994              :         {
    6995            0 :           if (GET_CODE (temp) == PARALLEL)
    6996            0 :             emit_group_move (target, temp);
    6997              :           else
    6998            0 :             emit_group_load (target, temp, TREE_TYPE (exp),
    6999            0 :                              int_size_in_bytes (TREE_TYPE (exp)));
    7000              :         }
    7001     14419138 :       else if (GET_CODE (temp) == PARALLEL)
    7002            0 :         emit_group_store (target, temp, TREE_TYPE (exp),
    7003            0 :                           int_size_in_bytes (TREE_TYPE (exp)));
    7004     14419138 :       else if (GET_MODE (temp) == BLKmode)
    7005       604302 :         emit_block_move (target, temp, expr_size (exp),
    7006              :                          (call_param_p
    7007              :                           ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
    7008              :       /* If we emit a nontemporal store, there is nothing else to do.  */
    7009     14116987 :       else if (nontemporal && emit_storent_insn (target, temp))
    7010              :         ;
    7011              :       else
    7012              :         {
    7013     14116970 :           if (reverse)
    7014          734 :             temp = flip_storage_order (GET_MODE (target), temp);
    7015     14116970 :           temp = force_operand (temp, target);
    7016     14116970 :           if (temp != target)
    7017     14115421 :             emit_move_insn (target, temp);
    7018              :         }
    7019              :     }
    7020              :   else
    7021      3129413 :     gcc_assert (!shortened_string_cst);
    7022              : 
    7023              :   return NULL_RTX;
    7024              : }
    7025              : 
    7026              : /* Return true if field F of structure TYPE is a flexible array.  */
    7027              : 
    7028              : static bool
    7029      3949179 : flexible_array_member_p (const_tree f, const_tree type)
    7030              : {
    7031      3949179 :   const_tree tf;
    7032              : 
    7033      3949179 :   tf = TREE_TYPE (f);
    7034      3949179 :   return (DECL_CHAIN (f) == NULL
    7035      1083409 :           && TREE_CODE (tf) == ARRAY_TYPE
    7036         2530 :           && TYPE_DOMAIN (tf)
    7037         2530 :           && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
    7038         2530 :           && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
    7039         2530 :           && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
    7040      3949218 :           && int_size_in_bytes (type) >= 0);
    7041              : }
    7042              : 
    7043              : /* If FOR_CTOR_P, return the number of top-level elements that a constructor
    7044              :    must have in order for it to completely initialize a value of type TYPE.
    7045              :    Return -1 if the number isn't known.
    7046              : 
    7047              :    If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE.  */
    7048              : 
    7049              : static HOST_WIDE_INT
    7050      3730816 : count_type_elements (const_tree type, bool for_ctor_p)
    7051              : {
    7052      3732169 :   switch (TREE_CODE (type))
    7053              :     {
    7054       155494 :     case ARRAY_TYPE:
    7055       155494 :       {
    7056       155494 :         tree nelts_minus_one;
    7057              : 
    7058       155494 :         nelts_minus_one = array_type_nelts_minus_one (type);
    7059       155494 :         if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one))
    7060              :           {
    7061       155483 :             unsigned HOST_WIDE_INT n;
    7062              : 
    7063       155483 :             n = tree_to_uhwi (nelts_minus_one) + 1;
    7064       155483 :             if (n == 0 || for_ctor_p)
    7065       154130 :               return n;
    7066              :             else
    7067         1353 :               return n * count_type_elements (TREE_TYPE (type), false);
    7068              :           }
    7069           11 :         return for_ctor_p ? -1 : 1;
    7070              :       }
    7071              : 
    7072      1824906 :     case RECORD_TYPE:
    7073      1824906 :       {
    7074      1824906 :         unsigned HOST_WIDE_INT n;
    7075      1824906 :         tree f;
    7076              : 
    7077      1824906 :         n = 0;
    7078     17352018 :         for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    7079     15527112 :           if (TREE_CODE (f) == FIELD_DECL)
    7080              :             {
    7081      4413297 :               if (!for_ctor_p)
    7082       464118 :                 n += count_type_elements (TREE_TYPE (f), false);
    7083      3949179 :               else if (!flexible_array_member_p (f, type))
    7084              :                 /* Don't count flexible arrays, which are not supposed
    7085              :                    to be initialized.  */
    7086      3949140 :                 n += 1;
    7087              :             }
    7088              : 
    7089      1824906 :         return n;
    7090              :       }
    7091              : 
    7092         3368 :     case UNION_TYPE:
    7093         3368 :     case QUAL_UNION_TYPE:
    7094         3368 :       {
    7095         3368 :         tree f;
    7096         3368 :         HOST_WIDE_INT n, m;
    7097              : 
    7098         3368 :         gcc_assert (!for_ctor_p);
    7099              :         /* Estimate the number of scalars in each field and pick the
    7100              :            maximum.  Other estimates would do instead; the idea is simply
    7101              :            to make sure that the estimate is not sensitive to the ordering
    7102              :            of the fields.  */
    7103         3368 :         n = 1;
    7104        76557 :         for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    7105        73189 :           if (TREE_CODE (f) == FIELD_DECL)
    7106              :             {
    7107        68694 :               m = count_type_elements (TREE_TYPE (f), false);
    7108              :               /* If the field doesn't span the whole union, add an extra
    7109              :                  scalar for the rest.  */
    7110        68694 :               if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
    7111        68694 :                                     TYPE_SIZE (type)) != 1)
    7112        48960 :                 m++;
    7113        68694 :               if (n < m)
    7114        73189 :                 n = m;
    7115              :             }
    7116              :         return n;
    7117              :       }
    7118              : 
    7119              :     case COMPLEX_TYPE:
    7120              :       return 2;
    7121              : 
    7122          421 :     case VECTOR_TYPE:
    7123          421 :       {
    7124          421 :         unsigned HOST_WIDE_INT nelts;
    7125          421 :         if (TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
    7126          421 :           return nelts;
    7127              :         else
    7128              :           return -1;
    7129              :       }
    7130              : 
    7131              :     case INTEGER_TYPE:
    7132              :     case REAL_TYPE:
    7133              :     case FIXED_POINT_TYPE:
    7134              :     case ENUMERAL_TYPE:
    7135              :     case BOOLEAN_TYPE:
    7136              :     case POINTER_TYPE:
    7137              :     case OFFSET_TYPE:
    7138              :     case REFERENCE_TYPE:
    7139              :     /* This could represent the C++ std::meta::info type.  */
    7140              :     case LANG_TYPE:
    7141              :     case NULLPTR_TYPE:
    7142              :     case OPAQUE_TYPE:
    7143              :     case BITINT_TYPE:
    7144              :       return 1;
    7145              : 
    7146            0 :     case ERROR_MARK:
    7147            0 :       return 0;
    7148              : 
    7149            0 :     case VOID_TYPE:
    7150            0 :     case METHOD_TYPE:
    7151            0 :     case FUNCTION_TYPE:
    7152            0 :     default:
    7153            0 :       gcc_unreachable ();
    7154              :     }
    7155              : }
    7156              : 
    7157              : /* Helper for categorize_ctor_elements.  Identical interface.  */
    7158              : 
    7159              : static bool
    7160      1552711 : categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
    7161              :                             HOST_WIDE_INT *p_unique_nz_elts,
    7162              :                             HOST_WIDE_INT *p_init_elts,
    7163              :                             ctor_completeness *p_complete)
    7164              : {
    7165      1552711 :   unsigned HOST_WIDE_INT idx;
    7166      1552711 :   HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
    7167      1552711 :   tree value, purpose, elt_type;
    7168              : 
    7169              :   /* Whether CTOR is a valid constant initializer, in accordance with what
    7170              :      initializer_constant_valid_p does.  If inferred from the constructor
    7171              :      elements, true until proven otherwise.  */
    7172      1552711 :   bool const_from_elts_p = constructor_static_from_elts_p (ctor);
    7173      1552711 :   bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
    7174              : 
    7175      1552711 :   nz_elts = 0;
    7176      1552711 :   unique_nz_elts = 0;
    7177      1552711 :   init_elts = 0;
    7178      1552711 :   num_fields = 0;
    7179      1552711 :   elt_type = NULL_TREE;
    7180              : 
    7181      5884685 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
    7182              :     {
    7183      4331974 :       HOST_WIDE_INT mult = 1;
    7184              : 
    7185      4331974 :       if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
    7186              :         {
    7187          854 :           tree lo_index = TREE_OPERAND (purpose, 0);
    7188          854 :           tree hi_index = TREE_OPERAND (purpose, 1);
    7189              : 
    7190          854 :           if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
    7191          854 :             mult = (tree_to_uhwi (hi_index)
    7192          854 :                     - tree_to_uhwi (lo_index) + 1);
    7193              :         }
    7194      4331974 :       num_fields += mult;
    7195      4331974 :       elt_type = TREE_TYPE (value);
    7196              : 
    7197      4331974 :       switch (TREE_CODE (value))
    7198              :         {
    7199       547168 :         case CONSTRUCTOR:
    7200       547168 :           {
    7201       547168 :             HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
    7202              : 
    7203       547168 :             bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
    7204              :                                                            &ic, p_complete);
    7205              : 
    7206       547168 :             nz_elts += mult * nz;
    7207       547168 :             unique_nz_elts += unz;
    7208       547168 :             init_elts += mult * ic;
    7209              : 
    7210       547168 :             if (const_from_elts_p && const_p)
    7211       333901 :               const_p = const_elt_p;
    7212              :           }
    7213       547168 :           break;
    7214              : 
    7215      2314411 :         case INTEGER_CST:
    7216      2314411 :         case REAL_CST:
    7217      2314411 :         case FIXED_CST:
    7218      2314411 :           if (!initializer_zerop (value))
    7219              :             {
    7220      1693628 :               nz_elts += mult;
    7221      1693628 :               unique_nz_elts++;
    7222              :             }
    7223      2314411 :           init_elts += mult;
    7224      2314411 :           break;
    7225              : 
    7226         6301 :         case STRING_CST:
    7227         6301 :           nz_elts += mult * TREE_STRING_LENGTH (value);
    7228         6301 :           unique_nz_elts += TREE_STRING_LENGTH (value);
    7229         6301 :           init_elts += mult * TREE_STRING_LENGTH (value);
    7230         6301 :           break;
    7231              : 
    7232          166 :         case RAW_DATA_CST:
    7233          166 :           nz_elts += mult * RAW_DATA_LENGTH (value);
    7234          166 :           unique_nz_elts += RAW_DATA_LENGTH (value);
    7235          166 :           init_elts += mult * RAW_DATA_LENGTH (value);
    7236          166 :           num_fields += mult * (RAW_DATA_LENGTH (value) - 1);
    7237          166 :           break;
    7238              : 
    7239         3234 :         case COMPLEX_CST:
    7240         3234 :           if (!initializer_zerop (TREE_REALPART (value)))
    7241              :             {
    7242         2630 :               nz_elts += mult;
    7243         2630 :               unique_nz_elts++;
    7244              :             }
    7245         3234 :           if (!initializer_zerop (TREE_IMAGPART (value)))
    7246              :             {
    7247         2272 :               nz_elts += mult;
    7248         2272 :               unique_nz_elts++;
    7249              :             }
    7250         3234 :           init_elts += 2 * mult;
    7251         3234 :           break;
    7252              : 
    7253         6420 :         case VECTOR_CST:
    7254         6420 :           {
    7255         6420 :             unsigned int nunits
    7256              :               = constant_lower_bound
    7257         6420 :               (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value)));
    7258        39931 :             for (unsigned int i = 0; i < nunits; ++i)
    7259              :               {
    7260        33511 :                 tree v = VECTOR_CST_ELT (value, i);
    7261        33511 :                 if (!initializer_zerop (v))
    7262              :                   {
    7263        19057 :                     nz_elts += mult;
    7264        19057 :                     unique_nz_elts++;
    7265              :                   }
    7266        33511 :                 init_elts += mult;
    7267              :               }
    7268              :           }
    7269              :           break;
    7270              : 
    7271      1454274 :         default:
    7272      1454274 :           {
    7273      1454274 :             HOST_WIDE_INT tc = count_type_elements (elt_type, false);
    7274      1454274 :             nz_elts += mult * tc;
    7275      1454274 :             unique_nz_elts += tc;
    7276      1454274 :             init_elts += mult * tc;
    7277              : 
    7278      1454274 :             if (const_from_elts_p && const_p)
    7279       599991 :               const_p
    7280       599991 :                 = initializer_constant_valid_p (value,
    7281              :                                                 elt_type,
    7282       599991 :                                                 TYPE_REVERSE_STORAGE_ORDER
    7283              :                                                 (TREE_TYPE (ctor)))
    7284              :                   != NULL_TREE;
    7285              :           }
    7286              :           break;
    7287              :         }
    7288              :     }
    7289              : 
    7290      1552711 :   if (!p_complete->sparse && !complete_ctor_at_level_p (TREE_TYPE (ctor),
    7291              :                                                 num_fields, elt_type))
    7292       187799 :     p_complete->sparse = true;
    7293      1364912 :   else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
    7294      1364912 :            || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
    7295              :     {
    7296        12727 :       if (!p_complete->sparse
    7297         8222 :           && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
    7298        22812 :           && (num_fields
    7299         5044 :               ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
    7300         5041 :                                   TYPE_SIZE (elt_type)) != 1
    7301            3 :               : type_has_padding_at_level_p (TREE_TYPE (ctor))))
    7302         3367 :         p_complete->sparse = true;
    7303         4855 :       else if (!p_complete->sparse && !p_complete->padded_union
    7304        19062 :                && (num_fields
    7305         4851 :                    ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
    7306         4851 :                                        TYPE_SIZE (elt_type)) != 1
    7307            0 :                    : type_has_padding_at_level_p (TREE_TYPE (ctor))))
    7308          640 :         p_complete->padded_union = true;
    7309              :     }
    7310      1352185 :   else if (!p_complete->sparse
    7311      1233900 :            && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
    7312      1214875 :                || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
    7313      1371239 :            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
    7314         2236 :     p_complete->sparse = true;
    7315      1231664 :   else if (!p_complete->sparse && !p_complete->padded_non_union
    7316      2533801 :            && type_has_padding_at_level_p (TREE_TYPE (ctor)))
    7317        15620 :     p_complete->padded_non_union = true;
    7318              : 
    7319      1552711 :   *p_nz_elts += nz_elts;
    7320      1552711 :   *p_unique_nz_elts += unique_nz_elts;
    7321      1552711 :   *p_init_elts += init_elts;
    7322              : 
    7323      1552711 :   return const_p;
    7324              : }
    7325              : 
    7326              : /* Examine CTOR to discover:
    7327              :    * how many scalar fields are set to nonzero values,
    7328              :      and place it in *P_NZ_ELTS;
    7329              :    * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
    7330              :      high - low + 1 (this can be useful for callers to determine ctors
    7331              :      that could be cheaply initialized with - perhaps nested - loops
    7332              :      compared to copied from huge read-only data),
    7333              :      and place it in *P_UNIQUE_NZ_ELTS;
    7334              :    * how many scalar fields in total are in CTOR,
    7335              :      and place it in *P_ELT_COUNT.
    7336              :    * whether the constructor is complete -- in the sense that every
    7337              :      meaningful byte is explicitly given a value --
    7338              :      and place it in *P_COMPLETE:
    7339              : 
    7340              :    Return whether or not CTOR is a valid static constant initializer, the same
    7341              :    as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0".  */
    7342              : 
    7343              : bool
    7344      1005543 : categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
    7345              :                           HOST_WIDE_INT *p_unique_nz_elts,
    7346              :                           HOST_WIDE_INT *p_init_elts,
    7347              :                           ctor_completeness *p_complete)
    7348              : {
    7349      1005543 :   *p_nz_elts = 0;
    7350      1005543 :   *p_unique_nz_elts = 0;
    7351      1005543 :   *p_init_elts = 0;
    7352      1005543 :   *p_complete = {};
    7353              : 
    7354      1005543 :   return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
    7355      1005543 :                                      p_init_elts, p_complete);
    7356              : }
    7357              : 
    7358              : /* Return true if constructor CTOR is simple enough to be materialized
    7359              :    in an integer mode register.  Limit the size to WORDS words, which
    7360              :    is 1 by default.  */
    7361              : 
    7362              : bool
    7363        23777 : immediate_const_ctor_p (const_tree ctor, unsigned int words)
    7364              : {
    7365              :   /* Allow function to be called with a VAR_DECL's DECL_INITIAL.  */
    7366        23777 :   if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
    7367              :     return false;
    7368              : 
    7369         2820 :   return TREE_CONSTANT (ctor)
    7370         2820 :          && !TREE_ADDRESSABLE (ctor)
    7371         2714 :          && CONSTRUCTOR_NELTS (ctor)
    7372         2688 :          && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
    7373          633 :          && int_expr_size (ctor) <= words * UNITS_PER_WORD
    7374         3009 :          && initializer_constant_valid_for_bitfield_p (ctor);
    7375              : }
    7376              : 
    7377              : /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
    7378              :    of which had type LAST_TYPE.  Each element was itself a complete
    7379              :    initializer, in the sense that every meaningful byte was explicitly
    7380              :    given a value.  Return true if the same is true for the constructor
    7381              :    as a whole.  */
    7382              : 
    7383              : bool
    7384      1753176 : complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
    7385              :                           const_tree last_type)
    7386              : {
    7387      1753176 :   if (TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE)
    7388              :     {
    7389         9446 :       if (num_elts == 0)
    7390              :         {
    7391           24 :           if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
    7392              :             return false;
    7393              : 
    7394              :           /* If the CONSTRUCTOR doesn't have any elts, it is
    7395              :              incomplete if the union has at least one field.  */
    7396          327 :           for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
    7397          324 :             if (TREE_CODE (f) == FIELD_DECL)
    7398              :               return false;
    7399              : 
    7400              :           return true;
    7401              :         }
    7402              : 
    7403         9422 :       gcc_assert (num_elts == 1 && last_type);
    7404              : 
    7405         9422 :       if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
    7406              :         /* ??? We could look at each element of the union, and find the
    7407              :            largest element.  Which would avoid comparing the size of the
    7408              :            initialized element against any tail padding in the union.
    7409              :            Doesn't seem worth the effort...  */
    7410          102 :         return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
    7411              : 
    7412              :       return true;
    7413              :     }
    7414              : 
    7415      1743730 :   return count_type_elements (type, true) == num_elts;
    7416              : }
    7417              : 
    7418              : /* Return true if EXP contains mostly (3/4) zeros.  */
    7419              : 
    7420              : static bool
    7421       370364 : mostly_zeros_p (const_tree exp)
    7422              : {
    7423       370364 :   if (TREE_CODE (exp) == CONSTRUCTOR)
    7424              :     {
    7425          197 :       HOST_WIDE_INT nz_elts, unz_elts, init_elts;
    7426          197 :       ctor_completeness complete_p;
    7427              : 
    7428          197 :       categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
    7429              :                                 &complete_p);
    7430          197 :       return complete_p.sparse || nz_elts < init_elts / 4;
    7431              :     }
    7432              : 
    7433       370167 :   return initializer_zerop (exp);
    7434              : }
    7435              : 
    7436              : /* Return true if EXP contains all zeros.  */
    7437              : 
    7438              : static bool
    7439         1108 : all_zeros_p (const_tree exp)
    7440              : {
    7441         1108 :   if (TREE_CODE (exp) == CONSTRUCTOR)
    7442              :     {
    7443         1108 :       HOST_WIDE_INT nz_elts, unz_elts, init_elts;
    7444         1108 :       ctor_completeness complete_p;
    7445              : 
    7446         1108 :       categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
    7447              :                                 &complete_p);
    7448         1108 :       return nz_elts == 0;
    7449              :     }
    7450              : 
    7451            0 :   return initializer_zerop (exp);
    7452              : }
    7453              : 
    7454              : /* Helper function for store_constructor.
    7455              :    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
    7456              :    CLEARED is as for store_constructor.
    7457              :    ALIAS_SET is the alias set to use for any stores.
    7458              :    If REVERSE is true, the store is to be done in reverse order.
    7459              : 
    7460              :    This provides a recursive shortcut back to store_constructor when it isn't
    7461              :    necessary to go through store_field.  This is so that we can pass through
    7462              :    the cleared field to let store_constructor know that we may not have to
    7463              :    clear a substructure if the outer structure has already been cleared.  */
    7464              : 
    7465              : static void
    7466        36952 : store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
    7467              :                          poly_uint64 bitregion_start,
    7468              :                          poly_uint64 bitregion_end,
    7469              :                          machine_mode mode,
    7470              :                          tree exp, int cleared,
    7471              :                          alias_set_type alias_set, bool reverse)
    7472              : {
    7473        36952 :   poly_int64 bytepos;
    7474        36952 :   poly_uint64 bytesize;
    7475        36952 :   if (TREE_CODE (exp) == CONSTRUCTOR
    7476              :       /* We can only call store_constructor recursively if the size and
    7477              :          bit position are on a byte boundary.  */
    7478        36952 :       && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
    7479           82 :       && maybe_ne (bitsize, 0U)
    7480        36870 :       && multiple_p (bitsize, BITS_PER_UNIT, &bytesize)
    7481              :       /* If we have a nonzero bitpos for a register target, then we just
    7482              :          let store_field do the bitfield handling.  This is unlikely to
    7483              :          generate unnecessary clear instructions anyways.  */
    7484        37034 :       && (known_eq (bitpos, 0) || MEM_P (target)))
    7485              :     {
    7486           82 :       if (MEM_P (target))
    7487              :         {
    7488           40 :           machine_mode target_mode = GET_MODE (target);
    7489           40 :           if (target_mode != BLKmode
    7490           40 :               && !multiple_p (bitpos, GET_MODE_ALIGNMENT (target_mode)))
    7491              :             target_mode = BLKmode;
    7492           40 :           target = adjust_address (target, target_mode, bytepos);
    7493              :         }
    7494              : 
    7495              : 
    7496              :       /* Update the alias set, if required.  */
    7497           40 :       if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
    7498          122 :           && MEM_ALIAS_SET (target) != 0)
    7499              :         {
    7500           36 :           target = copy_rtx (target);
    7501           36 :           set_mem_alias_set (target, alias_set);
    7502              :         }
    7503              : 
    7504           82 :       store_constructor (exp, target, cleared, bytesize, reverse);
    7505              :     }
    7506              :   else
    7507        36870 :     store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
    7508              :                  exp, alias_set, false, reverse);
    7509        36952 : }
    7510              : 
    7511              : 
    7512              : /* Returns the number of FIELD_DECLs in TYPE.  */
    7513              : 
    7514              : static int
    7515        69035 : fields_length (const_tree type)
    7516              : {
    7517        69035 :   tree t = TYPE_FIELDS (type);
    7518        69035 :   int count = 0;
    7519              : 
    7520       916940 :   for (; t; t = DECL_CHAIN (t))
    7521       847905 :     if (TREE_CODE (t) == FIELD_DECL)
    7522       300746 :       ++count;
    7523              : 
    7524        69035 :   return count;
    7525              : }
    7526              : 
    7527              : /* Store the value of constructor EXP into the rtx TARGET.
    7528              :    TARGET is either a REG or a MEM; we know it cannot conflict, since
    7529              :    safe_from_p has been called.
    7530              :    CLEARED is true if TARGET is known to have been zero'd.
    7531              :    If the constructor EXP has a vector type then elements of TARGET for which
    7532              :    there is no corresponding element in EXP are zero'd.  For a variable-length
    7533              :    vector type, only elements up to the minimum number of subparts of the type
    7534              :    are explicitly zero'd; any elements beyond that are implicitly zero.
    7535              :    SIZE is the number of bytes of TARGET we are allowed to modify: this
    7536              :    may not be the same as the size of EXP if we are assigning to a field
    7537              :    which has been packed to exclude padding bits.
    7538              :    If REVERSE is true, the store is to be done in reverse order.  */
    7539              : 
    7540              : void
    7541       251141 : store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
    7542              :                    bool reverse)
    7543              : {
    7544       251141 :   tree type = TREE_TYPE (exp);
    7545       251141 :   HOST_WIDE_INT exp_size = int_size_in_bytes (type);
    7546       251141 :   poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
    7547              : 
    7548       251141 :   switch (TREE_CODE (type))
    7549              :     {
    7550        69909 :     case RECORD_TYPE:
    7551        69909 :     case UNION_TYPE:
    7552        69909 :     case QUAL_UNION_TYPE:
    7553        69909 :       {
    7554        69909 :         unsigned HOST_WIDE_INT idx;
    7555        69909 :         tree field, value;
    7556              : 
    7557              :         /* The storage order is specified for every aggregate type.  */
    7558        69909 :         reverse = TYPE_REVERSE_STORAGE_ORDER (type);
    7559              : 
    7560              :         /* If size is zero or the target is already cleared, do nothing.  */
    7561        69909 :         if (known_eq (size, 0) || cleared)
    7562              :           cleared = 1;
    7563              :         /* We either clear the aggregate or indicate the value is dead.  */
    7564        69909 :         else if ((TREE_CODE (type) == UNION_TYPE
    7565        69909 :                   || TREE_CODE (type) == QUAL_UNION_TYPE)
    7566        70598 :                  && ! CONSTRUCTOR_ELTS (exp))
    7567              :           /* If the constructor is empty, clear the union.  */
    7568              :           {
    7569          640 :             clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
    7570          640 :             cleared = 1;
    7571              :           }
    7572              : 
    7573              :         /* If we are building a static constructor into a register,
    7574              :            set the initial value as zero so we can fold the value into
    7575              :            a constant.  But if more than one register is involved,
    7576              :            this probably loses.  */
    7577         4241 :         else if (REG_P (target) && TREE_STATIC (exp)
    7578        69859 :                  && known_le (GET_MODE_SIZE (GET_MODE (target)),
    7579              :                               REGMODE_NATURAL_SIZE (GET_MODE (target))))
    7580              :           {
    7581          234 :             emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
    7582          234 :             cleared = 1;
    7583              :           }
    7584              : 
    7585              :         /* If the constructor has fewer fields than the structure or
    7586              :            if we are initializing the structure to mostly zeros, clear
    7587              :            the whole structure first.  Don't do this if TARGET is a
    7588              :            register whose mode size isn't equal to SIZE since
    7589              :            clear_storage can't handle this case.  */
    7590        69035 :         else if (known_size_p (size)
    7591        69204 :                  && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
    7592          156 :                      || mostly_zeros_p (exp))
    7593       137918 :                  && (!REG_P (target)
    7594         8004 :                      || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
    7595              :           {
    7596        79584 :             clear_storage (target, gen_int_mode (size, Pmode),
    7597              :                            BLOCK_OP_NORMAL);
    7598        68883 :             cleared = 1;
    7599              :           }
    7600              : 
    7601        69909 :         if (REG_P (target) && !cleared)
    7602            5 :           emit_clobber (target);
    7603              : 
    7604              :         /* Store each element of the constructor into the
    7605              :            corresponding field of TARGET.  */
    7606        70255 :         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
    7607              :           {
    7608          346 :             machine_mode mode;
    7609          346 :             HOST_WIDE_INT bitsize;
    7610          346 :             HOST_WIDE_INT bitpos = 0;
    7611          346 :             tree offset;
    7612          346 :             rtx to_rtx = target;
    7613              : 
    7614              :             /* Just ignore missing fields.  We cleared the whole
    7615              :                structure, above, if any fields are missing.  */
    7616          346 :             if (field == 0)
    7617          346 :               continue;
    7618              : 
    7619          346 :             if (cleared && initializer_zerop (value))
    7620           17 :               continue;
    7621              : 
    7622              :             /* Variable sized arrays are ignored.  */
    7623          329 :             tree decl_size = DECL_SIZE (field);
    7624          329 :             if (!decl_size)
    7625            4 :               continue;
    7626              : 
    7627          325 :             if (tree_fits_uhwi_p (decl_size))
    7628          325 :               bitsize = tree_to_uhwi (decl_size);
    7629              :             else
    7630            0 :               gcc_unreachable ();
    7631              : 
    7632          325 :             mode = DECL_MODE (field);
    7633          325 :             if (DECL_BIT_FIELD (field))
    7634           24 :               mode = VOIDmode;
    7635              : 
    7636          325 :             offset = DECL_FIELD_OFFSET (field);
    7637          325 :             if (tree_fits_shwi_p (offset)
    7638          325 :                 && tree_fits_shwi_p (bit_position (field)))
    7639              :               {
    7640          325 :                 bitpos = int_bit_position (field);
    7641          325 :                 offset = NULL_TREE;
    7642              :               }
    7643              :             else
    7644            0 :               gcc_unreachable ();
    7645              : 
    7646              :             /* If this initializes a field that is smaller than a
    7647              :                word, at the start of a word, try to widen it to a full
    7648              :                word.  This special case allows us to output C++ member
    7649              :                function initializations in a form that the optimizers
    7650              :                can understand.  */
    7651          325 :             if (WORD_REGISTER_OPERATIONS
    7652              :                 && REG_P (target)
    7653              :                 && bitsize < BITS_PER_WORD
    7654              :                 && bitpos % BITS_PER_WORD == 0
    7655              :                 && GET_MODE_CLASS (mode) == MODE_INT
    7656              :                 && TREE_CODE (value) == INTEGER_CST
    7657              :                 && exp_size >= 0
    7658              :                 && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
    7659              :               {
    7660              :                 type = TREE_TYPE (value);
    7661              : 
    7662              :                 if (TYPE_PRECISION (type) < BITS_PER_WORD)
    7663              :                   {
    7664              :                     type = lang_hooks.types.type_for_mode
    7665              :                       (word_mode, TYPE_UNSIGNED (type));
    7666              :                     value = fold_convert (type, value);
    7667              :                     /* Make sure the bits beyond the original bitsize are zero
    7668              :                        so that we can correctly avoid extra zeroing stores in
    7669              :                        later constructor elements.  */
    7670              :                     tree bitsize_mask
    7671              :                       = wide_int_to_tree (type, wi::mask (bitsize, false,
    7672              :                                                            BITS_PER_WORD));
    7673              :                     value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
    7674              :                   }
    7675              : 
    7676              :                 if (BYTES_BIG_ENDIAN)
    7677              :                   value
    7678              :                    = fold_build2 (LSHIFT_EXPR, type, value,
    7679              :                                    build_int_cst (type,
    7680              :                                                   BITS_PER_WORD - bitsize));
    7681              :                 bitsize = BITS_PER_WORD;
    7682              :                 mode = word_mode;
    7683              :               }
    7684              : 
    7685          207 :             if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
    7686          532 :                 && DECL_NONADDRESSABLE_P (field))
    7687              :               {
    7688            0 :                 to_rtx = copy_rtx (to_rtx);
    7689            0 :                 MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
    7690              :               }
    7691              : 
    7692          325 :             store_constructor_field (to_rtx, bitsize, bitpos,
    7693          325 :                                      0, bitregion_end, mode,
    7694              :                                      value, cleared,
    7695          325 :                                      get_alias_set (TREE_TYPE (field)),
    7696              :                                      reverse);
    7697              :           }
    7698              :         break;
    7699              :       }
    7700        39421 :     case ARRAY_TYPE:
    7701        39421 :       {
    7702        39421 :         tree value, index;
    7703        39421 :         unsigned HOST_WIDE_INT i, j = 0;
    7704        39421 :         bool need_to_clear;
    7705        39421 :         tree domain;
    7706        39421 :         tree elttype = TREE_TYPE (type);
    7707        39421 :         bool const_bounds_p;
    7708        39421 :         unsigned HOST_WIDE_INT minelt = 0;
    7709        39421 :         unsigned HOST_WIDE_INT maxelt = 0;
    7710              : 
    7711              :         /* The storage order is specified for every aggregate type.  */
    7712        39421 :         reverse = TYPE_REVERSE_STORAGE_ORDER (type);
    7713              : 
    7714        39421 :         domain = TYPE_DOMAIN (type);
    7715        39421 :         const_bounds_p = (TYPE_MIN_VALUE (domain)
    7716        39421 :                           && TYPE_MAX_VALUE (domain)
    7717        39421 :                           && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain))
    7718        78842 :                           && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain)));
    7719              : 
    7720              :         /* If we have constant bounds for the range of the type, get them.  */
    7721        39421 :         if (const_bounds_p)
    7722              :           {
    7723        39421 :             minelt = tree_to_uhwi (TYPE_MIN_VALUE (domain));
    7724        39421 :             maxelt = tree_to_uhwi (TYPE_MAX_VALUE (domain));
    7725              :           }
    7726              : 
    7727              :         /* If the constructor has fewer elements than the array, clear
    7728              :            the whole array first.  Similarly if this is static
    7729              :            constructor of a non-BLKmode object.  */
    7730        39421 :         if (cleared)
    7731              :           need_to_clear = false;
    7732        39375 :         else if (REG_P (target) && TREE_STATIC (exp))
    7733              :           need_to_clear = true;
    7734              :         else
    7735              :           {
    7736        39268 :             unsigned HOST_WIDE_INT idx;
    7737        39268 :             unsigned HOST_WIDE_INT count = 0, zero_count = 0;
    7738        39268 :             need_to_clear = ! const_bounds_p;
    7739              : 
    7740              :             /* This loop is a more accurate version of the loop in
    7741              :                mostly_zeros_p (it handles RANGE_EXPR in an index).  It
    7742              :                is also needed to check for missing elements.  */
    7743        39276 :             FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
    7744              :               {
    7745            8 :                 unsigned HOST_WIDE_INT this_node_count;
    7746              : 
    7747            8 :                 if (need_to_clear)
    7748              :                   break;
    7749              : 
    7750            8 :                 if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
    7751              :                   {
    7752            0 :                     tree lo_index = TREE_OPERAND (index, 0);
    7753            0 :                     tree hi_index = TREE_OPERAND (index, 1);
    7754              : 
    7755            0 :                     if (! tree_fits_uhwi_p (lo_index)
    7756            0 :                         || ! tree_fits_uhwi_p (hi_index))
    7757              :                       {
    7758              :                         need_to_clear = true;
    7759              :                         break;
    7760              :                       }
    7761              : 
    7762            0 :                     this_node_count = (tree_to_uhwi (hi_index)
    7763            0 :                                        - tree_to_uhwi (lo_index) + 1);
    7764            0 :                   }
    7765            8 :                 else if (TREE_CODE (value) == RAW_DATA_CST)
    7766            0 :                   this_node_count = RAW_DATA_LENGTH (value);
    7767              :                 else
    7768              :                   this_node_count = 1;
    7769              : 
    7770            8 :                 count += this_node_count;
    7771            8 :                 if (mostly_zeros_p (value))
    7772            0 :                   zero_count += this_node_count;
    7773              :               }
    7774              : 
    7775              :             /* Clear the entire array first if there are any missing
    7776              :                elements, or if the incidence of zero elements is >=
    7777              :                75%.  */
    7778        39268 :             if (! need_to_clear
    7779        39268 :                 && (count < maxelt - minelt + 1
    7780            1 :                     || 4 * zero_count >= 3 * count))
    7781              :               need_to_clear = true;
    7782              :           }
    7783              : 
    7784        39374 :         if (need_to_clear && maybe_gt (size, 0))
    7785              :           {
    7786        39374 :             if (REG_P (target))
    7787         1661 :               emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
    7788              :             else
    7789        42481 :               clear_storage (target, gen_int_mode (size, Pmode),
    7790              :                              BLOCK_OP_NORMAL);
    7791              :             cleared = 1;
    7792              :           }
    7793              : 
    7794        39421 :         if (!cleared && REG_P (target))
    7795              :           /* Inform later passes that the old value is dead.  */
    7796            0 :           emit_clobber (target);
    7797              : 
    7798              :         /* Store each element of the constructor into the
    7799              :            corresponding element of TARGET, determined by counting the
    7800              :            elements.  */
    7801        40537 :         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
    7802              :           {
    7803         1116 :             machine_mode mode;
    7804         1116 :             poly_int64 bitsize;
    7805         1116 :             HOST_WIDE_INT bitpos;
    7806         1116 :             rtx xtarget = target;
    7807              : 
    7808         1116 :             if (cleared && initializer_zerop (value))
    7809              :               {
    7810          672 :                 if (TREE_CODE (value) == RAW_DATA_CST)
    7811            0 :                   j += RAW_DATA_LENGTH (value) - 1;
    7812          674 :                 continue;
    7813              :               }
    7814              : 
    7815          444 :             mode = TYPE_MODE (elttype);
    7816          444 :             if (mode != BLKmode)
    7817          888 :               bitsize = GET_MODE_BITSIZE (mode);
    7818            0 :             else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
    7819            0 :               bitsize = -1;
    7820              : 
    7821          444 :             if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
    7822              :               {
    7823            0 :                 tree lo_index = TREE_OPERAND (index, 0);
    7824            0 :                 tree hi_index = TREE_OPERAND (index, 1);
    7825            0 :                 rtx index_r;
    7826            0 :                 unsigned HOST_WIDE_INT lo, hi, count;
    7827            0 :                 tree offset;
    7828              : 
    7829            0 :                 gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
    7830              : 
    7831              :                 /* If the range is constant and "small", unroll the loop.  */
    7832            0 :                 if (const_bounds_p
    7833            0 :                     && tree_fits_uhwi_p (lo_index)
    7834            0 :                     && tree_fits_uhwi_p (hi_index)
    7835            0 :                     && (lo = tree_to_uhwi (lo_index),
    7836            0 :                         hi = tree_to_uhwi (hi_index),
    7837            0 :                         count = hi - lo + 1,
    7838            0 :                         (!MEM_P (target)
    7839            0 :                          || count <= 2
    7840            0 :                          || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
    7841            0 :                              && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
    7842              :                                  <= 40 * 8)))))
    7843              :                   {
    7844            0 :                     lo -= minelt;  hi -= minelt;
    7845            0 :                     for (; lo <= hi; lo++)
    7846              :                       {
    7847            0 :                         bitpos = lo * tree_to_uhwi (TYPE_SIZE (elttype));
    7848              : 
    7849            0 :                         if (MEM_P (target)
    7850            0 :                             && !MEM_KEEP_ALIAS_SET_P (target)
    7851            0 :                             && TREE_CODE (type) == ARRAY_TYPE
    7852            0 :                             && TYPE_NONALIASED_COMPONENT (type))
    7853              :                           {
    7854            0 :                             target = copy_rtx (target);
    7855            0 :                             MEM_KEEP_ALIAS_SET_P (target) = 1;
    7856              :                           }
    7857              : 
    7858            0 :                         store_constructor_field
    7859            0 :                           (target, bitsize, bitpos, 0, bitregion_end,
    7860              :                            mode, value, cleared,
    7861              :                            get_alias_set (elttype), reverse);
    7862              :                       }
    7863              :                   }
    7864              :                 else
    7865              :                   {
    7866            0 :                     rtx_code_label *loop_start = gen_label_rtx ();
    7867            0 :                     rtx_code_label *loop_end = gen_label_rtx ();
    7868            0 :                     tree exit_cond;
    7869              : 
    7870            0 :                     expand_normal (hi_index);
    7871              : 
    7872            0 :                     index = build_decl (EXPR_LOCATION (exp),
    7873              :                                         VAR_DECL, NULL_TREE, domain);
    7874            0 :                     index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
    7875            0 :                     SET_DECL_RTL (index, index_r);
    7876            0 :                     store_expr (lo_index, index_r, 0, false, reverse);
    7877              : 
    7878              :                     /* Build the head of the loop.  */
    7879            0 :                     do_pending_stack_adjust ();
    7880            0 :                     emit_label (loop_start);
    7881              : 
    7882              :                     /* Assign value to element index.  */
    7883            0 :                     offset = fold_build2 (MINUS_EXPR,
    7884              :                                           TREE_TYPE (index),
    7885              :                                           index,
    7886              :                                           TYPE_MIN_VALUE (domain));
    7887              : 
    7888            0 :                     offset = size_binop (MULT_EXPR,
    7889              :                                          fold_convert (sizetype, offset),
    7890              :                                          TYPE_SIZE_UNIT (elttype));
    7891              : 
    7892            0 :                     xtarget = offset_address (target,
    7893              :                                               expand_normal (offset),
    7894              :                                               highest_pow2_factor (offset));
    7895            0 :                     xtarget = adjust_address (xtarget, mode, 0);
    7896            0 :                     if (TREE_CODE (value) == CONSTRUCTOR)
    7897            0 :                       store_constructor (value, xtarget, cleared,
    7898              :                                          exact_div (bitsize, BITS_PER_UNIT),
    7899              :                                          reverse);
    7900              :                     else
    7901            0 :                       store_expr (value, xtarget, 0, false, reverse);
    7902              : 
    7903              :                     /* Generate a conditional jump to exit the loop.  */
    7904            0 :                     exit_cond = build2 (LT_EXPR, integer_type_node,
    7905              :                                         index, hi_index);
    7906            0 :                     jumpif (exit_cond, loop_end,
    7907              :                             profile_probability::uninitialized ());
    7908              : 
    7909              :                     /* Update the loop counter, and jump to the head of
    7910              :                        the loop.  */
    7911            0 :                     expand_assignment (index,
    7912            0 :                                        build2 (PLUS_EXPR, TREE_TYPE (index),
    7913              :                                                index, integer_one_node),
    7914              :                                        false);
    7915              : 
    7916            0 :                     emit_jump (loop_start);
    7917              : 
    7918              :                     /* Build the end of the loop.  */
    7919            0 :                     emit_label (loop_end);
    7920              :                   }
    7921              :               }
    7922          444 :             else if ((index && !tree_fits_uhwi_p (index))
    7923          444 :                      || !tree_fits_uhwi_p (TYPE_SIZE (elttype)))
    7924              :               {
    7925            0 :                 tree offset;
    7926              : 
    7927            0 :                 gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
    7928            0 :                 if (index)
    7929            0 :                   offset = fold_build2 (MINUS_EXPR,
    7930              :                                         TREE_TYPE (index),
    7931              :                                         index,
    7932              :                                         TYPE_MIN_VALUE (domain));
    7933              :                 else
    7934            0 :                   offset = size_int (i + j);
    7935              : 
    7936            0 :                 offset = size_binop (MULT_EXPR,
    7937              :                                      fold_convert (sizetype, offset),
    7938              :                                      TYPE_SIZE_UNIT (elttype));
    7939            0 :                 xtarget = offset_address (target,
    7940              :                                           expand_normal (offset),
    7941              :                                           highest_pow2_factor (offset));
    7942            0 :                 xtarget = adjust_address (xtarget, mode, 0);
    7943            0 :                 store_expr (value, xtarget, 0, false, reverse);
    7944              :               }
    7945              :             else
    7946              :               {
    7947          444 :                 if (index)
    7948          888 :                   bitpos = ((tree_to_uhwi (index) - minelt)
    7949          444 :                             * tree_to_uhwi (TYPE_SIZE (elttype)));
    7950              :                 else
    7951            0 :                   bitpos = ((i + j) * tree_to_uhwi (TYPE_SIZE (elttype)));
    7952              : 
    7953           12 :                 if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
    7954           12 :                     && TREE_CODE (type) == ARRAY_TYPE
    7955          456 :                     && TYPE_NONALIASED_COMPONENT (type))
    7956              :                   {
    7957            0 :                     target = copy_rtx (target);
    7958            0 :                     MEM_KEEP_ALIAS_SET_P (target) = 1;
    7959              :                   }
    7960          444 :                 if (TREE_CODE (value) != RAW_DATA_CST)
    7961          440 :                   store_constructor_field (target, bitsize, bitpos, 0,
    7962          440 :                                            bitregion_end, mode, value,
    7963              :                                            cleared, get_alias_set (elttype),
    7964              :                                            reverse);
    7965              :                 else
    7966              :                   {
    7967            4 :                     j += RAW_DATA_LENGTH (value) - 1;
    7968            4 :                     gcc_assert (known_eq (bitsize, BITS_PER_UNIT));
    7969            4 :                     rtx to_rtx = adjust_address (target, mode,
    7970              :                                                  bitpos / BITS_PER_UNIT);
    7971              : 
    7972            4 :                     if (to_rtx == target)
    7973            0 :                       to_rtx = copy_rtx (to_rtx);
    7974              : 
    7975            4 :                     if (!MEM_KEEP_ALIAS_SET_P (to_rtx)
    7976            8 :                         && MEM_ALIAS_SET (to_rtx) != 0)
    7977            0 :                       set_mem_alias_set (to_rtx, get_alias_set (elttype));
    7978              : 
    7979            8 :                     if (can_store_by_pieces (RAW_DATA_LENGTH (value),
    7980              :                                              raw_data_cst_read_str,
    7981              :                                              (void *) value,
    7982            4 :                                              MEM_ALIGN (target), false))
    7983              :                       {
    7984            4 :                         store_by_pieces (target, RAW_DATA_LENGTH (value),
    7985              :                                          raw_data_cst_read_str, (void *) value,
    7986            2 :                                          MEM_ALIGN (target), false,
    7987              :                                          RETURN_BEGIN);
    7988            2 :                         continue;
    7989              :                       }
    7990              : 
    7991            2 :                     elttype
    7992            2 :                       = build_array_type_nelts (TREE_TYPE (value),
    7993            2 :                                                 RAW_DATA_LENGTH (value));
    7994            2 :                     tree ctor = build_constructor_single (elttype, NULL_TREE,
    7995              :                                                           value);
    7996            2 :                     ctor = tree_output_constant_def (ctor);
    7997            2 :                     mode = TYPE_MODE (type);
    7998            2 :                     store_constructor_field (target,
    7999            2 :                                              bitsize * RAW_DATA_LENGTH (value),
    8000            2 :                                              bitpos, 0, bitregion_end, mode,
    8001              :                                              ctor, cleared,
    8002              :                                              get_alias_set (elttype), reverse);
    8003              :                   }
    8004              :               }
    8005              :           }
    8006              :         break;
    8007              :       }
    8008              : 
    8009       141811 :     case VECTOR_TYPE:
    8010       141811 :       {
    8011       141811 :         unsigned HOST_WIDE_INT idx;
    8012       141811 :         constructor_elt *ce;
    8013       141811 :         bool need_to_clear;
    8014       141811 :         insn_code icode = CODE_FOR_nothing;
    8015       141811 :         tree elt;
    8016       141811 :         tree elttype = TREE_TYPE (type);
    8017       141811 :         int elt_size = vector_element_bits (type);
    8018       141811 :         machine_mode eltmode = TYPE_MODE (elttype);
    8019       141811 :         poly_int64 bitsize;
    8020       141811 :         poly_int64 bitpos;
    8021       141811 :         rtvec vector = NULL;
    8022       141811 :         poly_uint64 n_elts;
    8023       141811 :         unsigned HOST_WIDE_INT const_n_elts;
    8024       141811 :         alias_set_type alias;
    8025       141811 :         bool vec_vec_init_p = false;
    8026       141811 :         machine_mode mode = GET_MODE (target);
    8027              : 
    8028       141811 :         gcc_assert (eltmode != BLKmode);
    8029              : 
    8030              :         /* Try using vec_duplicate_optab for uniform vectors.  */
    8031       141811 :         icode = optab_handler (vec_duplicate_optab, mode);
    8032       141811 :         if (!TREE_SIDE_EFFECTS (exp)
    8033       141811 :             && VECTOR_MODE_P (mode)
    8034       138255 :             && icode != CODE_FOR_nothing
    8035              :             /* If the vec_duplicate target pattern does not specify an element
    8036              :                mode check that eltmode is the normal inner mode of the
    8037              :                requested vector mode.  But if the target allows eltmode
    8038              :                explicitly go ahead and use it.  */
    8039        94735 :             && (eltmode == GET_MODE_INNER (mode)
    8040            0 :                 || insn_data[icode].operand[1].mode == eltmode)
    8041        94735 :             && (elt = uniform_vector_p (exp))
    8042       159584 :             && !VECTOR_TYPE_P (TREE_TYPE (elt)))
    8043              :           {
    8044        17773 :             class expand_operand ops[2];
    8045        17773 :             create_output_operand (&ops[0], target, mode);
    8046        17773 :             create_input_operand (&ops[1], expand_normal (elt), eltmode);
    8047        17773 :             expand_insn (icode, 2, ops);
    8048        17773 :             if (!rtx_equal_p (target, ops[0].value))
    8049            0 :               emit_move_insn (target, ops[0].value);
    8050        17773 :             break;
    8051              :           }
    8052              :         /* Use sign-extension for uniform boolean vectors with
    8053              :            integer modes and single-bit mask entries.
    8054              :            Effectively "vec_duplicate" for bitmasks.  */
    8055       124038 :         if (elt_size == 1
    8056          146 :             && !TREE_SIDE_EFFECTS (exp)
    8057          146 :             && VECTOR_BOOLEAN_TYPE_P (type)
    8058          146 :             && SCALAR_INT_MODE_P (TYPE_MODE (type))
    8059          146 :             && (elt = uniform_vector_p (exp))
    8060          143 :             && !VECTOR_TYPE_P (TREE_TYPE (elt))
    8061       124038 :             && !BYTES_BIG_ENDIAN)
    8062              :           {
    8063          143 :             rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
    8064              :                                  expand_normal (elt));
    8065          143 :             rtx tmp = gen_reg_rtx (mode);
    8066          143 :             convert_move (tmp, op0, 0);
    8067              : 
    8068              :             /* Ensure no excess bits are set.
    8069              :                GCN needs this for nunits < 64.
    8070              :                x86 needs this for nunits < 8.  */
    8071          143 :             unsigned int nunits = TYPE_VECTOR_SUBPARTS (type).to_constant ();
    8072          143 :             if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
    8073            2 :               tmp = expand_binop (mode, and_optab, tmp,
    8074            2 :                                   GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
    8075              :                                   target, true, OPTAB_WIDEN);
    8076          143 :             if (tmp != target)
    8077          141 :               emit_move_insn (target, tmp);
    8078              :             break;
    8079              :           }
    8080              : 
    8081       123895 :         n_elts = TYPE_VECTOR_SUBPARTS (type);
    8082       123895 :         if (REG_P (target)
    8083       120676 :             && VECTOR_MODE_P (mode))
    8084              :           {
    8085       120482 :             const_n_elts = 0;
    8086       120482 :             if (CONSTRUCTOR_NELTS (exp)
    8087       120482 :                 && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
    8088              :                     == VECTOR_TYPE))
    8089              :               {
    8090         1465 :                 tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
    8091         1465 :                 gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
    8092              :                                       * TYPE_VECTOR_SUBPARTS (etype),
    8093              :                                       n_elts));
    8094              : 
    8095         4395 :                 icode = convert_optab_handler (vec_init_optab, mode,
    8096         1465 :                                                TYPE_MODE (etype));
    8097         1465 :                 const_n_elts = CONSTRUCTOR_NELTS (exp);
    8098         1465 :                 vec_vec_init_p = icode != CODE_FOR_nothing;
    8099              :               }
    8100       238034 :             else if (exact_div (n_elts, GET_MODE_NUNITS (eltmode))
    8101       119017 :                         .is_constant (&const_n_elts))
    8102              :               {
    8103              :                 /* For a non-const type vector, we check it is made up of
    8104              :                    similarly non-const type vectors. */
    8105       119017 :                 icode = convert_optab_handler (vec_init_optab, mode, eltmode);
    8106              :               }
    8107              :             else
    8108              :               {
    8109              :                 /* Handle variable-length vector types.  */
    8110              :                 icode = convert_optab_handler (vec_init_optab, mode, eltmode);
    8111              :                 const_n_elts = constant_lower_bound (n_elts);
    8112              :               }
    8113              : 
    8114       120482 :             if (const_n_elts && icode != CODE_FOR_nothing)
    8115              :               {
    8116       119736 :                 vector = rtvec_alloc (const_n_elts);
    8117       565714 :                 for (unsigned int k = 0; k < const_n_elts; k++)
    8118       326242 :                   RTVEC_ELT (vector, k) = CONST0_RTX (eltmode);
    8119              :               }
    8120              :           }
    8121              :         else
    8122              :           gcc_assert (n_elts.is_constant ());
    8123              : 
    8124              :         /* Compute the size of the elements in the CTOR.  It differs
    8125              :            from the size of the vector type elements only when the
    8126              :            CTOR elements are vectors themselves.  */
    8127       123895 :         tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
    8128       123895 :                          ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
    8129       123895 :                          : elttype);
    8130       123895 :         if (VECTOR_TYPE_P (val_type))
    8131         1815 :           bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
    8132              :         else
    8133       122080 :           bitsize = elt_size;
    8134              : 
    8135              :         /* If the constructor has fewer elements than the vector,
    8136              :            clear the whole array first.  Similarly if this is static
    8137              :            constructor of a non-BLKmode object.  */
    8138       123895 :         if (cleared)
    8139              :           need_to_clear = false;
    8140       123895 :         else if (REG_P (target) && TREE_STATIC (exp))
    8141              :           need_to_clear = true;
    8142              :         else
    8143              :           {
    8144              :             poly_uint64 count = 0, zero_count = 0;
    8145              :             tree value;
    8146              : 
    8147       494054 :             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
    8148              :               {
    8149       370159 :                 poly_int64 n_elts_here = exact_div (bitsize, elt_size);
    8150       370159 :                 count += n_elts_here;
    8151       370159 :                 if (mostly_zeros_p (value))
    8152       370159 :                   zero_count += n_elts_here;
    8153              :               }
    8154              : 
    8155              :             /* Clear the entire vector first if there are any missing elements,
    8156              :                or if the incidence of zero elements is >= 75%.  */
    8157       123895 :             need_to_clear = (maybe_lt (count, n_elts)
    8158       123895 :                              || maybe_gt (4 * zero_count, 3 * count));
    8159              :           }
    8160              : 
    8161         1308 :         if (need_to_clear && maybe_gt (size, 0) && !vector)
    8162              :           {
    8163          761 :             if (REG_P (target))
    8164           25 :               emit_move_insn (target, CONST0_RTX (mode));
    8165              :             else
    8166          736 :               clear_storage (target, gen_int_mode (size, Pmode),
    8167              :                              BLOCK_OP_NORMAL);
    8168              :             cleared = 1;
    8169              :           }
    8170              : 
    8171              :         /* Inform later passes that the old value is dead.  */
    8172       123895 :         if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
    8173              :           {
    8174          594 :             emit_move_insn (target, CONST0_RTX (mode));
    8175          594 :             cleared = 1;
    8176              :           }
    8177              : 
    8178       123895 :         if (MEM_P (target))
    8179         3219 :           alias = MEM_ALIAS_SET (target);
    8180              :         else
    8181       120676 :           alias = get_alias_set (elttype);
    8182              : 
    8183              :         /* Store each element of the constructor into the corresponding
    8184              :            element of TARGET, determined by counting the elements.  */
    8185       123895 :         HOST_WIDE_INT chunk_size = 0;
    8186       123895 :         bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
    8187              :                                                      &chunk_size);
    8188       123895 :         gcc_assert (chunk_multiple_p || vec_vec_init_p);
    8189              : 
    8190       494054 :         for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
    8191              :              idx++)
    8192              :           {
    8193       370159 :             HOST_WIDE_INT eltpos;
    8194       370159 :             tree value = ce->value;
    8195              : 
    8196       370159 :             if (cleared && initializer_zerop (value))
    8197         8817 :               continue;
    8198              : 
    8199       361342 :             if (ce->index)
    8200        49556 :               eltpos = tree_to_uhwi (ce->index);
    8201              :             else
    8202       311786 :               eltpos = idx * chunk_size;
    8203              : 
    8204       361342 :             if (vector)
    8205              :               {
    8206       325157 :                 if (vec_vec_init_p)
    8207              :                   {
    8208         2826 :                     gcc_assert (ce->index == NULL_TREE);
    8209         2826 :                     gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
    8210         2826 :                     eltpos = idx;
    8211              :                   }
    8212              :                 else
    8213       322331 :                   gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
    8214       325157 :                 RTVEC_ELT (vector, eltpos) = expand_normal (value);
    8215              :               }
    8216              :             else
    8217              :               {
    8218        36185 :                 machine_mode value_mode
    8219        36185 :                   = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
    8220        36185 :                      ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
    8221        36185 :                 bitpos = eltpos * elt_size;
    8222        36185 :                 store_constructor_field (target, bitsize, bitpos, 0,
    8223        36185 :                                          bitregion_end, value_mode,
    8224              :                                          value, cleared, alias, reverse);
    8225              :               }
    8226              :           }
    8227              : 
    8228       123895 :         if (vector)
    8229       119736 :           emit_insn (GEN_FCN (icode) (target,
    8230              :                                       gen_rtx_PARALLEL (mode, vector)));
    8231              :         break;
    8232              :       }
    8233              : 
    8234            0 :     default:
    8235            0 :       gcc_unreachable ();
    8236              :     }
    8237       251141 : }
    8238              : 
    8239              : /* Store the value of EXP (an expression tree)
    8240              :    into a subfield of TARGET which has mode MODE and occupies
    8241              :    BITSIZE bits, starting BITPOS bits from the start of TARGET.
    8242              :    If MODE is VOIDmode, it means that we are storing into a bit-field.
    8243              : 
    8244              :    BITREGION_START is bitpos of the first bitfield in this region.
    8245              :    BITREGION_END is the bitpos of the ending bitfield in this region.
    8246              :    These two fields are 0, if the C++ memory model does not apply,
    8247              :    or we are not interested in keeping track of bitfield regions.
    8248              : 
    8249              :    Always return const0_rtx unless we have something particular to
    8250              :    return.
    8251              : 
    8252              :    ALIAS_SET is the alias set for the destination.  This value will
    8253              :    (in general) be different from that for TARGET, since TARGET is a
    8254              :    reference to the containing structure.
    8255              : 
    8256              :    If NONTEMPORAL is true, try generating a nontemporal store.
    8257              : 
    8258              :    If REVERSE is true, the store is to be done in reverse order.  */
    8259              : 
    8260              : static rtx
    8261      4831075 : store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
    8262              :              poly_uint64 bitregion_start, poly_uint64 bitregion_end,
    8263              :              machine_mode mode, tree exp,
    8264              :              alias_set_type alias_set, bool nontemporal,  bool reverse)
    8265              : {
    8266      4831075 :   if (TREE_CODE (exp) == ERROR_MARK)
    8267            0 :     return const0_rtx;
    8268              : 
    8269              :   /* If we have nothing to store, do nothing unless the expression has
    8270              :      side-effects.  Don't do that for zero sized addressable lhs of
    8271              :      calls.  */
    8272      4831075 :   if (known_eq (bitsize, 0)
    8273      4831075 :       && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
    8274            3 :           || TREE_CODE (exp) != CALL_EXPR))
    8275            0 :     return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
    8276              : 
    8277      4831075 :   if (GET_CODE (target) == CONCAT)
    8278              :     {
    8279              :       /* We're storing into a struct containing a single __complex.  */
    8280              : 
    8281            0 :       gcc_assert (known_eq (bitpos, 0));
    8282            0 :       return store_expr (exp, target, 0, nontemporal, reverse);
    8283              :     }
    8284              : 
    8285              :   /* If the structure is in a register or if the component
    8286              :      is a bit field, we cannot use addressing to access it.
    8287              :      Use bit-field techniques or SUBREG to store in it.  */
    8288              : 
    8289      4831075 :   poly_int64 decl_bitsize;
    8290      4831075 :   if (mode == VOIDmode
    8291      4763878 :       || (mode != BLKmode && ! direct_store[(int) mode]
    8292         5311 :           && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
    8293         5309 :           && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
    8294      4758598 :       || REG_P (target)
    8295      4069314 :       || GET_CODE (target) == SUBREG
    8296              :       /* If the field isn't aligned enough to store as an ordinary memref,
    8297              :          store it as a bit field.  */
    8298      4069314 :       || (mode != BLKmode
    8299      3953593 :           && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
    8300      7817580 :                 || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
    8301        47522 :                && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
    8302      3953593 :               || !multiple_p (bitpos, BITS_PER_UNIT)))
    8303      4069314 :       || (known_size_p (bitsize)
    8304      4069302 :           && mode != BLKmode
    8305      3953593 :           && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
    8306              :       /* If the RHS and field are a constant size and the size of the
    8307              :          RHS isn't the same size as the bitfield, we must use bitfield
    8308              :          operations.  */
    8309      4069305 :       || (known_size_p (bitsize)
    8310      4069293 :           && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
    8311      4831349 :           && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
    8312              :                        bitsize)
    8313              :           /* Except for initialization of full bytes from a CONSTRUCTOR, which
    8314              :              we will handle specially below.  */
    8315           34 :           && !(TREE_CODE (exp) == CONSTRUCTOR
    8316           11 :                && multiple_p (bitsize, BITS_PER_UNIT))
    8317              :           /* And except for bitwise copying of TREE_ADDRESSABLE types,
    8318              :              where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
    8319              :              includes some extra padding.  store_expr / expand_expr will in
    8320              :              that case call get_inner_reference that will have the bitsize
    8321              :              we check here and thus the block move will not clobber the
    8322              :              padding that shouldn't be clobbered.  In the future we could
    8323              :              replace the TREE_ADDRESSABLE check with a check that
    8324              :              get_base_address needs to live in memory.  */
    8325           23 :           && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
    8326            9 :               || TREE_CODE (exp) != COMPONENT_REF
    8327            6 :               || !multiple_p (bitsize, BITS_PER_UNIT)
    8328            6 :               || !multiple_p (bitpos, BITS_PER_UNIT)
    8329            6 :               || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
    8330              :                                    &decl_bitsize)
    8331            6 :               || maybe_ne (decl_bitsize, bitsize))
    8332              :           /* A call with an addressable return type and return-slot
    8333              :              optimization must not need bitfield operations but we must
    8334              :              pass down the original target.  */
    8335           17 :           && (TREE_CODE (exp) != CALL_EXPR
    8336            6 :               || !TREE_ADDRESSABLE (TREE_TYPE (exp))
    8337            0 :               || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
    8338              :       /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
    8339              :          decl we must use bitfield operations.  */
    8340      8900363 :       || (known_size_p (bitsize)
    8341      4069276 :           && TREE_CODE (exp) == MEM_REF
    8342        32931 :           && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
    8343        26989 :           && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    8344        20417 :           && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
    8345         5699 :           && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
    8346              :     {
    8347       762056 :       rtx temp;
    8348       762056 :       gimple *nop_def;
    8349              : 
    8350              :       /* If EXP is a NOP_EXPR of precision less than its mode, then that
    8351              :          implies a mask operation.  If the precision is the same size as
    8352              :          the field we're storing into, that mask is redundant.  This is
    8353              :          particularly common with bit field assignments generated by the
    8354              :          C front end.  */
    8355       762056 :       nop_def = get_def_for_expr (exp, NOP_EXPR);
    8356       762056 :       if (nop_def)
    8357              :         {
    8358         5546 :           tree type = TREE_TYPE (exp);
    8359         5546 :           if (INTEGRAL_TYPE_P (type)
    8360         5336 :               && maybe_ne (TYPE_PRECISION (type),
    8361        10672 :                            GET_MODE_BITSIZE (TYPE_MODE (type)))
    8362         8855 :               && known_eq (bitsize, TYPE_PRECISION (type)))
    8363              :             {
    8364         3309 :               tree op = gimple_assign_rhs1 (nop_def);
    8365         3309 :               type = TREE_TYPE (op);
    8366         3309 :               if (INTEGRAL_TYPE_P (type)
    8367         3309 :                   && known_ge (TYPE_PRECISION (type), bitsize))
    8368              :                 exp = op;
    8369              :             }
    8370              :         }
    8371              : 
    8372       762056 :       temp = expand_normal (exp);
    8373              : 
    8374              :       /* We don't support variable-sized BLKmode bitfields, since our
    8375              :          handling of BLKmode is bound up with the ability to break
    8376              :          things into words.  */
    8377       762056 :       gcc_assert (mode != BLKmode || bitsize.is_constant ());
    8378              : 
    8379              :       /* Handle calls that return values in multiple non-contiguous locations.
    8380              :          The Irix 6 ABI has examples of this.  */
    8381       762056 :       if (GET_CODE (temp) == PARALLEL)
    8382              :         {
    8383            6 :           HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
    8384            6 :           machine_mode temp_mode = GET_MODE (temp);
    8385            6 :           if (temp_mode == BLKmode || temp_mode == VOIDmode)
    8386            6 :             temp_mode
    8387            6 :               = smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
    8388            6 :           rtx temp_target = gen_reg_rtx (temp_mode);
    8389            6 :           emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
    8390            6 :           temp = temp_target;
    8391              :         }
    8392              : 
    8393              :       /* Handle calls that return BLKmode values in registers.  */
    8394       762050 :       else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
    8395              :         {
    8396            0 :           rtx temp_target = gen_reg_rtx (GET_MODE (temp));
    8397            0 :           copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
    8398            0 :           temp = temp_target;
    8399              :         }
    8400              : 
    8401              :       /* If the value has aggregate type and an integral mode then, if BITSIZE
    8402              :          is narrower than this mode and this is for big-endian data, we first
    8403              :          need to put the value into the low-order bits for store_bit_field,
    8404              :          except when MODE is BLKmode and BITSIZE larger than the word size
    8405              :          (see the handling of fields larger than a word in store_bit_field).
    8406              :          Moreover, the field may be not aligned on a byte boundary; in this
    8407              :          case, if it has reverse storage order, it needs to be accessed as a
    8408              :          scalar field with reverse storage order and we must first put the
    8409              :          value into target order.  */
    8410       762056 :       scalar_int_mode temp_mode;
    8411      1521999 :       if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
    8412       762808 :           && is_int_mode (GET_MODE (temp), &temp_mode))
    8413              :         {
    8414         2518 :           HOST_WIDE_INT size = GET_MODE_BITSIZE (temp_mode);
    8415              : 
    8416         2518 :           reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
    8417              : 
    8418         2518 :           if (reverse)
    8419            0 :             temp = flip_storage_order (temp_mode, temp);
    8420              : 
    8421         2518 :           gcc_checking_assert (known_le (bitsize, size));
    8422         2518 :           if (maybe_lt (bitsize, size)
    8423         2518 :               && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
    8424              :               /* Use of to_constant for BLKmode was checked above.  */
    8425              :               && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
    8426            0 :             temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
    8427              :                                  size - bitsize, NULL_RTX, 1);
    8428              :         }
    8429              : 
    8430              :       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE.  */
    8431       694859 :       if (mode != VOIDmode && mode != BLKmode
    8432      1456618 :           && mode != TYPE_MODE (TREE_TYPE (exp)))
    8433            4 :         temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
    8434              : 
    8435              :       /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
    8436              :          and BITPOS must be aligned on a byte boundary.  If so, we simply do
    8437              :          a block copy.  Likewise for a BLKmode-like TARGET.  */
    8438       762056 :       if (GET_MODE (temp) == BLKmode
    8439       762056 :           && (GET_MODE (target) == BLKmode
    8440          202 :               || (MEM_P (target)
    8441            0 :                   && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
    8442            0 :                   && multiple_p (bitpos, BITS_PER_UNIT)
    8443            0 :                   && multiple_p (bitsize, BITS_PER_UNIT))))
    8444              :         {
    8445           89 :           gcc_assert (MEM_P (target) && MEM_P (temp));
    8446           89 :           poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
    8447           89 :           poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
    8448              : 
    8449           89 :           target = adjust_address (target, VOIDmode, bytepos);
    8450           89 :           emit_block_move (target, temp,
    8451           89 :                            gen_int_mode (bytesize, Pmode),
    8452              :                            BLOCK_OP_NORMAL);
    8453              : 
    8454           89 :           return const0_rtx;
    8455              :         }
    8456              : 
    8457              :       /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
    8458              :          word size, we need to load the value (see again store_bit_field).  */
    8459       761985 :       if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
    8460              :         {
    8461           81 :           temp_mode = smallest_int_mode_for_size (bitsize).require ();
    8462           81 :           temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
    8463              :                                     temp_mode, false, NULL);
    8464              :         }
    8465              : 
    8466              :       /* Store the value in the bitfield.  */
    8467       761967 :       gcc_checking_assert (known_ge (bitpos, 0));
    8468       761967 :       store_bit_field (target, bitsize, bitpos,
    8469              :                        bitregion_start, bitregion_end,
    8470              :                        mode, temp, reverse, false);
    8471              : 
    8472       761967 :       return const0_rtx;
    8473              :     }
    8474              :   else
    8475              :     {
    8476              :       /* Now build a reference to just the desired component.  */
    8477      4069019 :       rtx to_rtx = adjust_address (target, mode,
    8478              :                                    exact_div (bitpos, BITS_PER_UNIT));
    8479              : 
    8480      4069019 :       if (to_rtx == target)
    8481      1299478 :         to_rtx = copy_rtx (to_rtx);
    8482              : 
    8483      7861727 :       if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
    8484      3533689 :         set_mem_alias_set (to_rtx, alias_set);
    8485              : 
    8486              :       /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
    8487              :          into a target smaller than its type; handle that case now.  */
    8488      4069019 :       if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (bitsize))
    8489              :         {
    8490        70250 :           poly_int64 bytesize = exact_div (bitsize, BITS_PER_UNIT);
    8491        70250 :           store_constructor (exp, to_rtx, 0, bytesize, reverse);
    8492        70250 :           return to_rtx;
    8493              :         }
    8494              : 
    8495      3998769 :       return store_expr (exp, to_rtx, 0, nontemporal, reverse);
    8496              :     }
    8497              : }
    8498              : 
    8499              : /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
    8500              :    an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
    8501              :    codes and find the ultimate containing object, which we return.
    8502              : 
    8503              :    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
    8504              :    bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
    8505              :    storage order of the field.
    8506              :    If the position of the field is variable, we store a tree
    8507              :    giving the variable offset (in units) in *POFFSET.
    8508              :    This offset is in addition to the bit position.
    8509              :    If the position is not variable, we store 0 in *POFFSET.
    8510              : 
    8511              :    If any of the extraction expressions is volatile,
    8512              :    we store 1 in *PVOLATILEP.  Otherwise we don't change that.
    8513              : 
    8514              :    If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
    8515              :    Otherwise, it is a mode that can be used to access the field.
    8516              : 
    8517              :    If the field describes a variable-sized object, *PMODE is set to
    8518              :    BLKmode and *PBITSIZE is set to -1.  An access cannot be made in
    8519              :    this case, but the address of the object can be found.  */
    8520              : 
    8521              : tree
    8522    296757171 : get_inner_reference (tree exp, poly_int64 *pbitsize,
    8523              :                      poly_int64 *pbitpos, tree *poffset,
    8524              :                      machine_mode *pmode, int *punsignedp,
    8525              :                      int *preversep, int *pvolatilep)
    8526              : {
    8527    296757171 :   tree size_tree = 0;
    8528    296757171 :   machine_mode mode = VOIDmode;
    8529    296757171 :   bool blkmode_bitfield = false;
    8530    296757171 :   tree offset = size_zero_node;
    8531    296757171 :   poly_offset_int bit_offset = 0;
    8532              : 
    8533              :   /* First get the mode, signedness, storage order and size.  We do this from
    8534              :      just the outermost expression.  */
    8535    296757171 :   *pbitsize = -1;
    8536    296757171 :   if (TREE_CODE (exp) == COMPONENT_REF)
    8537              :     {
    8538    127450484 :       tree field = TREE_OPERAND (exp, 1);
    8539    127450484 :       size_tree = DECL_SIZE (field);
    8540    127450484 :       if (flag_strict_volatile_bitfields > 0
    8541           58 :           && TREE_THIS_VOLATILE (exp)
    8542           40 :           && DECL_BIT_FIELD_TYPE (field)
    8543    127450506 :           && DECL_MODE (field) != BLKmode)
    8544              :         /* Volatile bitfields should be accessed in the mode of the
    8545              :              field's type, not the mode computed based on the bit
    8546              :              size.  */
    8547           22 :         mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
    8548    127450462 :       else if (!DECL_BIT_FIELD (field))
    8549              :         {
    8550    126106919 :           mode = DECL_MODE (field);
    8551              :           /* For vector fields re-check the target flags, as DECL_MODE
    8552              :              could have been set with different target flags than
    8553              :              the current function has.  */
    8554    126106919 :           if (VECTOR_TYPE_P (TREE_TYPE (field))
    8555    126106919 :               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
    8556       380549 :             mode = TYPE_MODE (TREE_TYPE (field));
    8557              :         }
    8558      1343543 :       else if (DECL_MODE (field) == BLKmode)
    8559          624 :         blkmode_bitfield = true;
    8560              : 
    8561    127450484 :       *punsignedp = DECL_UNSIGNED (field);
    8562              :     }
    8563    169306687 :   else if (TREE_CODE (exp) == BIT_FIELD_REF)
    8564              :     {
    8565       620749 :       size_tree = TREE_OPERAND (exp, 1);
    8566      1241079 :       *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
    8567      1091096 :                      || TYPE_UNSIGNED (TREE_TYPE (exp)));
    8568              : 
    8569              :       /* For vector element types with the correct size of access or for
    8570              :          vector typed accesses use the mode of the access type.  */
    8571       620749 :       if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
    8572       467020 :            && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
    8573       419988 :            && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
    8574       667816 :           || VECTOR_TYPE_P (TREE_TYPE (exp)))
    8575       444236 :         mode = TYPE_MODE (TREE_TYPE (exp));
    8576              :     }
    8577              :   else
    8578              :     {
    8579    168685938 :       mode = TYPE_MODE (TREE_TYPE (exp));
    8580    168685938 :       *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
    8581              : 
    8582    168685938 :       if (mode == BLKmode)
    8583     74664226 :         size_tree = TYPE_SIZE (TREE_TYPE (exp));
    8584              :       else
    8585    188043424 :         *pbitsize = GET_MODE_BITSIZE (mode);
    8586              :     }
    8587              : 
    8588    296757171 :   if (size_tree != 0)
    8589              :     {
    8590    201904894 :       if (!poly_int_tree_p (size_tree, pbitsize))
    8591       484706 :         mode = BLKmode, *pbitsize = -1;
    8592              :     }
    8593              : 
    8594    296757171 :   *preversep = reverse_storage_order_for_component_p (exp);
    8595              : 
    8596              :   /* Compute cumulative bit-offset for nested component-refs and array-refs,
    8597              :      and find the ultimate containing object.  */
    8598    758465607 :   while (1)
    8599              :     {
    8600    527611389 :       switch (TREE_CODE (exp))
    8601              :         {
    8602       620749 :         case BIT_FIELD_REF:
    8603       620749 :           bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
    8604       620749 :           break;
    8605              : 
    8606    194185229 :         case COMPONENT_REF:
    8607    194185229 :           {
    8608    194185229 :             tree field = TREE_OPERAND (exp, 1);
    8609    194185229 :             tree this_offset = component_ref_field_offset (exp);
    8610              : 
    8611              :             /* If this field hasn't been filled in yet, don't go past it.
    8612              :                This should only happen when folding expressions made during
    8613              :                type construction.  */
    8614    194185229 :             if (this_offset == 0)
    8615              :               break;
    8616              : 
    8617    194185229 :             offset = size_binop (PLUS_EXPR, offset, this_offset);
    8618    194185229 :             bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
    8619              : 
    8620              :             /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN.  */
    8621              :           }
    8622    194185229 :           break;
    8623              : 
    8624     32735488 :         case ARRAY_REF:
    8625     32735488 :         case ARRAY_RANGE_REF:
    8626     32735488 :           {
    8627     32735488 :             tree index = TREE_OPERAND (exp, 1);
    8628     32735488 :             tree low_bound = array_ref_low_bound (exp);
    8629     32735488 :             tree unit_size = array_ref_element_size (exp);
    8630              : 
    8631              :             /* We assume all arrays have sizes that are a multiple of a byte.
    8632              :                First subtract the lower bound, if any, in the type of the
    8633              :                index, then convert to sizetype and multiply by the size of
    8634              :                the array element.  */
    8635     32735488 :             if (! integer_zerop (low_bound))
    8636       972991 :               index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
    8637              :                                    index, low_bound);
    8638              : 
    8639     32735488 :             offset = size_binop (PLUS_EXPR, offset,
    8640              :                                  size_binop (MULT_EXPR,
    8641              :                                              fold_convert (sizetype, index),
    8642              :                                              unit_size));
    8643              :           }
    8644     32735488 :           break;
    8645              : 
    8646              :         case REALPART_EXPR:
    8647              :           break;
    8648              : 
    8649              :         case IMAGPART_EXPR:
    8650    230854218 :           bit_offset += *pbitsize;
    8651              :           break;
    8652              : 
    8653              :         case VIEW_CONVERT_EXPR:
    8654              :           break;
    8655              : 
    8656     93140549 :         case MEM_REF:
    8657              :           /* Hand back the decl for MEM[&decl, off].  */
    8658     93140549 :           if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
    8659              :             {
    8660     21858875 :               tree off = TREE_OPERAND (exp, 1);
    8661     21858875 :               if (!integer_zerop (off))
    8662              :                 {
    8663     12442420 :                   poly_offset_int boff = mem_ref_offset (exp);
    8664     12442420 :                   boff <<= LOG2_BITS_PER_UNIT;
    8665     12442420 :                   bit_offset += boff;
    8666              :                 }
    8667     21858875 :               exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    8668              :             }
    8669     93140549 :           goto done;
    8670              : 
    8671    203616622 :         default:
    8672    203616622 :           goto done;
    8673              :         }
    8674              : 
    8675              :       /* If any reference in the chain is volatile, the effect is volatile.  */
    8676    230854218 :       if (TREE_THIS_VOLATILE (exp))
    8677       567030 :         *pvolatilep = 1;
    8678              : 
    8679    230854218 :       exp = TREE_OPERAND (exp, 0);
    8680    230854218 :     }
    8681    296757171 :  done:
    8682              : 
    8683              :   /* If OFFSET is constant, see if we can return the whole thing as a
    8684              :      constant bit position.  Make sure to handle overflow during
    8685              :      this conversion.  */
    8686    296757171 :   if (poly_int_tree_p (offset))
    8687              :     {
    8688    283027521 :       poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
    8689    283027521 :                                       TYPE_PRECISION (sizetype));
    8690    283027521 :       tem <<= LOG2_BITS_PER_UNIT;
    8691    283027521 :       tem += bit_offset;
    8692    283027521 :       if (tem.to_shwi (pbitpos))
    8693    283026093 :         *poffset = offset = NULL_TREE;
    8694              :     }
    8695              : 
    8696              :   /* Otherwise, split it up.  */
    8697    283027521 :   if (offset)
    8698              :     {
    8699              :       /* Avoid returning a negative bitpos as this may wreak havoc later.  */
    8700     13731078 :       if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
    8701              :         {
    8702          303 :           *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
    8703          303 :           poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
    8704          303 :           offset = size_binop (PLUS_EXPR, offset,
    8705              :                                build_int_cst (sizetype, bytes.force_shwi ()));
    8706              :         }
    8707              : 
    8708     13731078 :       *poffset = offset;
    8709              :     }
    8710              : 
    8711              :   /* We can use BLKmode for a byte-aligned BLKmode bitfield.  */
    8712    296757171 :   if (mode == VOIDmode
    8713      5847053 :       && blkmode_bitfield
    8714          624 :       && multiple_p (*pbitpos, BITS_PER_UNIT)
    8715    296757659 :       && multiple_p (*pbitsize, BITS_PER_UNIT))
    8716            5 :     *pmode = BLKmode;
    8717              :   else
    8718    296757166 :     *pmode = mode;
    8719              : 
    8720    296757171 :   return exp;
    8721              : }
    8722              : 
    8723              : /* Alignment in bits the TARGET of an assignment may be assumed to have.  */
    8724              : 
    8725              : static unsigned HOST_WIDE_INT
    8726       515781 : target_align (const_tree target)
    8727              : {
    8728              :   /* We might have a chain of nested references with intermediate misaligning
    8729              :      bitfields components, so need to recurse to find out.  */
    8730              : 
    8731       515781 :   unsigned HOST_WIDE_INT this_align, outer_align;
    8732              : 
    8733       515781 :   switch (TREE_CODE (target))
    8734              :     {
    8735              :     case BIT_FIELD_REF:
    8736              :       return 1;
    8737              : 
    8738       140519 :     case COMPONENT_REF:
    8739       140519 :       this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
    8740       140519 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8741       140519 :       return MIN (this_align, outer_align);
    8742              : 
    8743       190889 :     case ARRAY_REF:
    8744       190889 :     case ARRAY_RANGE_REF:
    8745       190889 :       this_align = TYPE_ALIGN (TREE_TYPE (target));
    8746       190889 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8747       190889 :       return MIN (this_align, outer_align);
    8748              : 
    8749         4700 :     CASE_CONVERT:
    8750         4700 :     case NON_LVALUE_EXPR:
    8751         4700 :     case VIEW_CONVERT_EXPR:
    8752         4700 :       this_align = TYPE_ALIGN (TREE_TYPE (target));
    8753         4700 :       outer_align = target_align (TREE_OPERAND (target, 0));
    8754         4700 :       return MAX (this_align, outer_align);
    8755              : 
    8756       179668 :     default:
    8757       179668 :       return TYPE_ALIGN (TREE_TYPE (target));
    8758              :     }
    8759              : }
    8760              : 
    8761              : 
    8762              : /* Given an rtx VALUE that may contain additions and multiplications, return
    8763              :    an equivalent value that just refers to a register, memory, or constant.
    8764              :    This is done by generating instructions to perform the arithmetic and
    8765              :    returning a pseudo-register containing the value.
    8766              : 
    8767              :    The returned value may be a REG, SUBREG, MEM or constant.  */
    8768              : 
    8769              : rtx
    8770     31843232 : force_operand (rtx value, rtx target)
    8771              : {
    8772     31843232 :   rtx op1, op2;
    8773              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
    8774     31843232 :   rtx subtarget = get_subtarget (target);
    8775     31843232 :   enum rtx_code code = GET_CODE (value);
    8776              : 
    8777              :   /* Check for subreg applied to an expression produced by loop optimizer.  */
    8778     31843232 :   if (code == SUBREG
    8779       306799 :       && !REG_P (SUBREG_REG (value))
    8780          200 :       && !MEM_P (SUBREG_REG (value)))
    8781              :     {
    8782          200 :       value
    8783          200 :         = simplify_gen_subreg (GET_MODE (value),
    8784          200 :                                force_reg (GET_MODE (SUBREG_REG (value)),
    8785              :                                           force_operand (SUBREG_REG (value),
    8786              :                                                          NULL_RTX)),
    8787          200 :                                GET_MODE (SUBREG_REG (value)),
    8788          200 :                                SUBREG_BYTE (value));
    8789          200 :       code = GET_CODE (value);
    8790              :     }
    8791              : 
    8792              :   /* Check for a PIC address load.  */
    8793     31843232 :   if ((code == PLUS || code == MINUS)
    8794      3810524 :       && XEXP (value, 0) == pic_offset_table_rtx
    8795         1927 :       && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
    8796         1927 :           || GET_CODE (XEXP (value, 1)) == LABEL_REF
    8797         1927 :           || GET_CODE (XEXP (value, 1)) == CONST))
    8798              :     {
    8799          184 :       if (!subtarget)
    8800          184 :         subtarget = gen_reg_rtx (GET_MODE (value));
    8801          184 :       emit_move_insn (subtarget, value);
    8802          184 :       return subtarget;
    8803              :     }
    8804              : 
    8805     31843048 :   if (ARITHMETIC_P (value))
    8806              :     {
    8807      3935345 :       op2 = XEXP (value, 1);
    8808      3935345 :       if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
    8809      3935345 :         subtarget = 0;
    8810      3935345 :       if (code == MINUS && CONST_INT_P (op2))
    8811              :         {
    8812            0 :           code = PLUS;
    8813            0 :           op2 = negate_rtx (GET_MODE (value), op2);
    8814              :         }
    8815              : 
    8816              :       /* Check for an addition with OP2 a constant integer and our first
    8817              :          operand a PLUS of a virtual register and something else.  In that
    8818              :          case, we want to emit the sum of the virtual register and the
    8819              :          constant first and then add the other value.  This allows virtual
    8820              :          register instantiation to simply modify the constant rather than
    8821              :          creating another one around this addition.  */
    8822      3749116 :       if (code == PLUS && CONST_INT_P (op2)
    8823      3377343 :           && GET_CODE (XEXP (value, 0)) == PLUS
    8824        65070 :           && REG_P (XEXP (XEXP (value, 0), 0))
    8825      3942874 :           && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
    8826              :         {
    8827         1150 :           rtx temp = expand_simple_binop (GET_MODE (value), code,
    8828              :                                           XEXP (XEXP (value, 0), 0), op2,
    8829              :                                           subtarget, 0, OPTAB_LIB_WIDEN);
    8830         1150 :           return expand_simple_binop (GET_MODE (value), code, temp,
    8831         1150 :                                       force_operand (XEXP (XEXP (value,
    8832              :                                                                  0), 1), 0),
    8833         1150 :                                       target, 0, OPTAB_LIB_WIDEN);
    8834              :         }
    8835              : 
    8836      3934195 :       op1 = force_operand (XEXP (value, 0), subtarget);
    8837      3934195 :       op2 = force_operand (op2, NULL_RTX);
    8838      3934195 :       switch (code)
    8839              :         {
    8840        98658 :         case MULT:
    8841        98658 :           return expand_mult (GET_MODE (value), op1, op2, target, 1);
    8842          506 :         case DIV:
    8843          506 :           if (!INTEGRAL_MODE_P (GET_MODE (value)))
    8844          506 :             return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8845          506 :                                         target, 1, OPTAB_LIB_WIDEN);
    8846              :           else
    8847            0 :             return expand_divmod (0,
    8848              :                                   FLOAT_MODE_P (GET_MODE (value))
    8849              :                                   ? RDIV_EXPR : TRUNC_DIV_EXPR,
    8850            0 :                                   GET_MODE (value), op1, op2, target, 0);
    8851            0 :         case MOD:
    8852            0 :           return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
    8853            0 :                                 target, 0);
    8854          348 :         case UDIV:
    8855          348 :           return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
    8856          348 :                                 target, 1);
    8857            0 :         case UMOD:
    8858            0 :           return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
    8859            0 :                                 target, 1);
    8860          138 :         case ASHIFTRT:
    8861          138 :           return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8862          138 :                                       target, 0, OPTAB_LIB_WIDEN);
    8863      3834545 :         default:
    8864      3834545 :           return expand_simple_binop (GET_MODE (value), code, op1, op2,
    8865      3834545 :                                       target, 1, OPTAB_LIB_WIDEN);
    8866              :         }
    8867              :     }
    8868     27907703 :   if (UNARY_P (value))
    8869              :     {
    8870        25712 :       if (!target)
    8871        11582 :         target = gen_reg_rtx (GET_MODE (value));
    8872              :       /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
    8873              :          while FIX with floating point mode rounds toward zero.  So, some
    8874              :          targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
    8875              :          to express rounding toward zero during the conversion to int.
    8876              :          expand_fix isn't able to handle that, it can only handle
    8877              :          FIX/UNSIGNED_FIX from floating point mode to integral one.  */
    8878        25712 :       if ((code == FIX || code == UNSIGNED_FIX)
    8879            8 :           && GET_CODE (XEXP (value, 0)) == FIX
    8880            0 :           && (GET_MODE (XEXP (value, 0))
    8881            0 :               == GET_MODE (XEXP (XEXP (value, 0), 0))))
    8882            0 :         op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
    8883              :       else
    8884        25712 :         op1 = force_operand (XEXP (value, 0), NULL_RTX);
    8885        25712 :       switch (code)
    8886              :         {
    8887        11716 :         case ZERO_EXTEND:
    8888        11716 :         case SIGN_EXTEND:
    8889        11716 :         case TRUNCATE:
    8890        11716 :         case FLOAT_EXTEND:
    8891        11716 :         case FLOAT_TRUNCATE:
    8892        11716 :           convert_move (target, op1, code == ZERO_EXTEND);
    8893        11716 :           return target;
    8894              : 
    8895            8 :         case FIX:
    8896            8 :         case UNSIGNED_FIX:
    8897            8 :           expand_fix (target, op1, code == UNSIGNED_FIX);
    8898            8 :           return target;
    8899              : 
    8900           72 :         case FLOAT:
    8901           72 :         case UNSIGNED_FLOAT:
    8902           72 :           expand_float (target, op1, code == UNSIGNED_FLOAT);
    8903           72 :           return target;
    8904              : 
    8905        13916 :         default:
    8906        13916 :           return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
    8907              :         }
    8908              :     }
    8909              : 
    8910              : #ifdef INSN_SCHEDULING
    8911              :   /* On machines that have insn scheduling, we want all memory reference to be
    8912              :      explicit, so we need to deal with such paradoxical SUBREGs.  */
    8913     27881991 :   if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
    8914            0 :     value
    8915            0 :       = simplify_gen_subreg (GET_MODE (value),
    8916            0 :                              force_reg (GET_MODE (SUBREG_REG (value)),
    8917              :                                         force_operand (SUBREG_REG (value),
    8918              :                                                        NULL_RTX)),
    8919              :                              GET_MODE (SUBREG_REG (value)),
    8920            0 :                              SUBREG_BYTE (value));
    8921              : #endif
    8922              : 
    8923              :   return value;
    8924              : }
    8925              : 
    8926              : /* Subroutine of expand_expr: return true iff there is no way that
    8927              :    EXP can reference X, which is being modified.  TOP_P is nonzero if this
    8928              :    call is going to be used to determine whether we need a temporary
    8929              :    for EXP, as opposed to a recursive call to this function.
    8930              : 
    8931              :    It is always safe for this routine to return false since it merely
    8932              :    searches for optimization opportunities.  */
    8933              : 
    8934              : bool
    8935      8933714 : safe_from_p (const_rtx x, tree exp, int top_p)
    8936              : {
    8937      8933730 :   rtx exp_rtl = 0;
    8938      8933730 :   int i, nops;
    8939              : 
    8940      8933730 :   if (x == 0
    8941              :       /* If EXP has varying size, we MUST use a target since we currently
    8942              :          have no way of allocating temporaries of variable size
    8943              :          (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
    8944              :          So we assume here that something at a higher level has prevented a
    8945              :          clash.  This is somewhat bogus, but the best we can do.  Only
    8946              :          do this when X is BLKmode and when we are at the top level.  */
    8947      2025380 :       || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
    8948      1887878 :           && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
    8949            0 :           && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
    8950            0 :               || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
    8951            0 :               || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
    8952              :               != INTEGER_CST)
    8953            0 :           && GET_MODE (x) == BLKmode)
    8954              :       /* If X is in the outgoing argument area, it is always safe.  */
    8955     10959110 :       || (MEM_P (x)
    8956       181378 :           && (XEXP (x, 0) == virtual_outgoing_args_rtx
    8957       181378 :               || (GET_CODE (XEXP (x, 0)) == PLUS
    8958       132686 :                   && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
    8959              :     return true;
    8960              : 
    8961              :   /* If this is a subreg of a hard register, declare it unsafe, otherwise,
    8962              :      find the underlying pseudo.  */
    8963      2025380 :   if (GET_CODE (x) == SUBREG)
    8964              :     {
    8965            0 :       x = SUBREG_REG (x);
    8966            0 :       if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
    8967              :         return false;
    8968              :     }
    8969              : 
    8970              :   /* Now look at our tree code and possibly recurse.  */
    8971      2025380 :   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
    8972              :     {
    8973          600 :     case tcc_declaration:
    8974          600 :       exp_rtl = DECL_RTL_IF_SET (exp);
    8975              :       break;
    8976              : 
    8977              :     case tcc_constant:
    8978              :       return true;
    8979              : 
    8980       873758 :     case tcc_exceptional:
    8981       873758 :       if (TREE_CODE (exp) == TREE_LIST)
    8982              :         {
    8983            0 :           while (1)
    8984              :             {
    8985            0 :               if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
    8986              :                 return false;
    8987            0 :               exp = TREE_CHAIN (exp);
    8988            0 :               if (!exp)
    8989              :                 return true;
    8990            0 :               if (TREE_CODE (exp) != TREE_LIST)
    8991              :                 return safe_from_p (x, exp, 0);
    8992              :             }
    8993              :         }
    8994       873758 :       else if (TREE_CODE (exp) == CONSTRUCTOR)
    8995              :         {
    8996              :           constructor_elt *ce;
    8997              :           unsigned HOST_WIDE_INT idx;
    8998              : 
    8999      8230798 :           FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
    9000         5832 :             if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
    9001       137077 :                 || !safe_from_p (x, ce->value, 0))
    9002              :               return false;
    9003              :           return true;
    9004              :         }
    9005       728449 :       else if (TREE_CODE (exp) == ERROR_MARK)
    9006              :         return true;    /* An already-visited SAVE_EXPR? */
    9007              :       else
    9008              :         return false;
    9009              : 
    9010            0 :     case tcc_statement:
    9011              :       /* The only case we look at here is the DECL_INITIAL inside a
    9012              :          DECL_EXPR.  */
    9013            0 :       return (TREE_CODE (exp) != DECL_EXPR
    9014            0 :               || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
    9015            0 :               || !DECL_INITIAL (DECL_EXPR_DECL (exp))
    9016            0 :               || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
    9017              : 
    9018            0 :     case tcc_binary:
    9019            0 :     case tcc_comparison:
    9020            0 :       if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
    9021              :         return false;
    9022              :       /* Fall through.  */
    9023              : 
    9024           16 :     case tcc_unary:
    9025           16 :       return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
    9026              : 
    9027          471 :     case tcc_expression:
    9028          471 :     case tcc_reference:
    9029          471 :     case tcc_vl_exp:
    9030              :       /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
    9031              :          the expression.  If it is set, we conflict iff we are that rtx or
    9032              :          both are in memory.  Otherwise, we check all operands of the
    9033              :          expression recursively.  */
    9034              : 
    9035          471 :       switch (TREE_CODE (exp))
    9036              :         {
    9037          383 :         case ADDR_EXPR:
    9038              :           /* If the operand is static or we are static, we can't conflict.
    9039              :              Likewise if we don't conflict with the operand at all.  */
    9040          383 :           if (staticp (TREE_OPERAND (exp, 0))
    9041          233 :               || TREE_STATIC (exp)
    9042          616 :               || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
    9043              :             return true;
    9044              : 
    9045              :           /* Otherwise, the only way this can conflict is if we are taking
    9046              :              the address of a DECL a that address if part of X, which is
    9047              :              very rare.  */
    9048            0 :           exp = TREE_OPERAND (exp, 0);
    9049            0 :           if (DECL_P (exp))
    9050              :             {
    9051            0 :               if (!DECL_RTL_SET_P (exp)
    9052            0 :                   || !MEM_P (DECL_RTL (exp)))
    9053              :                 return false;
    9054              :               else
    9055            0 :                 exp_rtl = XEXP (DECL_RTL (exp), 0);
    9056              :             }
    9057              :           break;
    9058              : 
    9059           73 :         case MEM_REF:
    9060           73 :           if (MEM_P (x)
    9061           73 :               && alias_sets_conflict_p (MEM_ALIAS_SET (x),
    9062              :                                         get_alias_set (exp)))
    9063              :             return false;
    9064              :           break;
    9065              : 
    9066            0 :         case CALL_EXPR:
    9067              :           /* Assume that the call will clobber all hard registers and
    9068              :              all of memory.  */
    9069            0 :           if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
    9070            0 :               || MEM_P (x))
    9071              :             return false;
    9072              :           break;
    9073              : 
    9074            0 :         case WITH_CLEANUP_EXPR:
    9075            0 :         case CLEANUP_POINT_EXPR:
    9076              :           /* Lowered by gimplify.cc.  */
    9077            0 :           gcc_unreachable ();
    9078              : 
    9079            0 :         case SAVE_EXPR:
    9080            0 :           return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
    9081              : 
    9082              :         default:
    9083              :           break;
    9084              :         }
    9085              : 
    9086              :       /* If we have an rtx, we do not need to scan our operands.  */
    9087            0 :       if (exp_rtl)
    9088              :         break;
    9089              : 
    9090           88 :       nops = TREE_OPERAND_LENGTH (exp);
    9091          371 :       for (i = 0; i < nops; i++)
    9092          195 :         if (TREE_OPERAND (exp, i) != 0
    9093          195 :             && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
    9094              :           return false;
    9095              : 
    9096              :       break;
    9097              : 
    9098            0 :     case tcc_type:
    9099              :       /* Should never get a type here.  */
    9100            0 :       gcc_unreachable ();
    9101              :     }
    9102              : 
    9103              :   /* If we have an rtl, find any enclosed object.  Then see if we conflict
    9104              :      with it.  */
    9105          392 :   if (exp_rtl)
    9106              :     {
    9107          304 :       if (GET_CODE (exp_rtl) == SUBREG)
    9108              :         {
    9109            0 :           exp_rtl = SUBREG_REG (exp_rtl);
    9110            0 :           if (REG_P (exp_rtl)
    9111            0 :               && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
    9112              :             return false;
    9113              :         }
    9114              : 
    9115              :       /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
    9116              :          are memory and they conflict.  */
    9117          304 :       return ! (rtx_equal_p (x, exp_rtl)
    9118          304 :                 || (MEM_P (x) && MEM_P (exp_rtl)
    9119            4 :                     && true_dependence (exp_rtl, VOIDmode, x)));
    9120              :     }
    9121              : 
    9122              :   /* If we reach here, it is safe.  */
    9123              :   return true;
    9124              : }
    9125              : 
    9126              : 
    9127              : /* Return the highest power of two that EXP is known to be a multiple of.
    9128              :    This is used in updating alignment of MEMs in array references.  */
    9129              : 
    9130              : unsigned HOST_WIDE_INT
    9131     33427040 : highest_pow2_factor (const_tree exp)
    9132              : {
    9133     33427040 :   unsigned HOST_WIDE_INT ret;
    9134     33427040 :   int trailing_zeros = tree_ctz (exp);
    9135     33427040 :   if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
    9136     23463306 :     return BIGGEST_ALIGNMENT;
    9137      9963734 :   ret = HOST_WIDE_INT_1U << trailing_zeros;
    9138     19461378 :   if (ret > BIGGEST_ALIGNMENT)
    9139      6632259 :     return BIGGEST_ALIGNMENT;
    9140              :   return ret;
    9141              : }
    9142              : 
    9143              : /* Similar, except that the alignment requirements of TARGET are
    9144              :    taken into account.  Assume it is at least as aligned as its
    9145              :    type, unless it is a COMPONENT_REF in which case the layout of
    9146              :    the structure gives the alignment.  */
    9147              : 
    9148              : static unsigned HOST_WIDE_INT
    9149       179673 : highest_pow2_factor_for_target (const_tree target, const_tree exp)
    9150              : {
    9151       179673 :   unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
    9152       179673 :   unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
    9153              : 
    9154       179673 :   return MAX (factor, talign);
    9155              : }
    9156              : 
    9157              : /* Convert the tree comparison code TCODE to the rtl one where the
    9158              :    signedness is UNSIGNEDP.  */
    9159              : 
    9160              : enum rtx_code
    9161        21534 : convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
    9162              : {
    9163        21534 :   enum rtx_code code;
    9164        21534 :   switch (tcode)
    9165              :     {
    9166              :     case EQ_EXPR:
    9167              :       code = EQ;
    9168              :       break;
    9169         2456 :     case NE_EXPR:
    9170         2456 :       code = NE;
    9171         2456 :       break;
    9172         4012 :     case LT_EXPR:
    9173         4012 :       code = unsignedp ? LTU : LT;
    9174              :       break;
    9175         3039 :     case LE_EXPR:
    9176         3039 :       code = unsignedp ? LEU : LE;
    9177              :       break;
    9178         3226 :     case GT_EXPR:
    9179         3226 :       code = unsignedp ? GTU : GT;
    9180              :       break;
    9181         4302 :     case GE_EXPR:
    9182         4302 :       code = unsignedp ? GEU : GE;
    9183              :       break;
    9184           35 :     case UNORDERED_EXPR:
    9185           35 :       code = UNORDERED;
    9186           35 :       break;
    9187           35 :     case ORDERED_EXPR:
    9188           35 :       code = ORDERED;
    9189           35 :       break;
    9190           10 :     case UNLT_EXPR:
    9191           10 :       code = UNLT;
    9192           10 :       break;
    9193           19 :     case UNLE_EXPR:
    9194           19 :       code = UNLE;
    9195           19 :       break;
    9196           10 :     case UNGT_EXPR:
    9197           10 :       code = UNGT;
    9198           10 :       break;
    9199           11 :     case UNGE_EXPR:
    9200           11 :       code = UNGE;
    9201           11 :       break;
    9202            4 :     case UNEQ_EXPR:
    9203            4 :       code = UNEQ;
    9204            4 :       break;
    9205            4 :     case LTGT_EXPR:
    9206            4 :       code = LTGT;
    9207            4 :       break;
    9208              : 
    9209            0 :     default:
    9210            0 :       gcc_unreachable ();
    9211              :     }
    9212        21534 :   return code;
    9213              : }
    9214              : 
    9215              : /* Subroutine of expand_expr.  Expand the two operands of a binary
    9216              :    expression EXP0 and EXP1 placing the results in OP0 and OP1.
    9217              :    The value may be stored in TARGET if TARGET is nonzero.  The
    9218              :    MODIFIER argument is as documented by expand_expr.  */
    9219              : 
    9220              : void
    9221      8315708 : expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
    9222              :                  enum expand_modifier modifier)
    9223              : {
    9224      8315708 :   if (! safe_from_p (target, exp1, 1))
    9225       604335 :     target = 0;
    9226      8315708 :   if (operand_equal_p (exp0, exp1, 0))
    9227              :     {
    9228        47930 :       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
    9229        47930 :       *op1 = copy_rtx (*op0);
    9230              :     }
    9231              :   else
    9232              :     {
    9233      8267778 :       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
    9234      8267778 :       *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
    9235              :     }
    9236      8315708 : }
    9237              : 
    9238              : 
    9239              : /* Return a MEM that contains constant EXP.  DEFER is as for
    9240              :    output_constant_def and MODIFIER is as for expand_expr.  */
    9241              : 
    9242              : static rtx
    9243      2976030 : expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
    9244              : {
    9245      2976030 :   rtx mem;
    9246              : 
    9247      2976030 :   mem = output_constant_def (exp, defer);
    9248      2976030 :   if (modifier != EXPAND_INITIALIZER)
    9249      1898416 :     mem = use_anchored_address (mem);
    9250      2976030 :   return mem;
    9251              : }
    9252              : 
    9253              : /* A subroutine of expand_expr_addr_expr.  Evaluate the address of EXP.
    9254              :    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
    9255              : 
    9256              : static rtx
    9257     14565217 : expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
    9258              :                          enum expand_modifier modifier, addr_space_t as)
    9259              : {
    9260     14565217 :   rtx result, subtarget;
    9261     14565217 :   tree inner, offset;
    9262     14565217 :   poly_int64 bitsize, bitpos;
    9263     14565217 :   int unsignedp, reversep, volatilep = 0;
    9264     14565217 :   machine_mode mode1;
    9265              : 
    9266              :   /* If we are taking the address of a constant and are at the top level,
    9267              :      we have to use output_constant_def since we can't call force_const_mem
    9268              :      at top level.  */
    9269              :   /* ??? This should be considered a front-end bug.  We should not be
    9270              :      generating ADDR_EXPR of something that isn't an LVALUE.  The only
    9271              :      exception here is STRING_CST.  */
    9272     14565217 :   if (CONSTANT_CLASS_P (exp))
    9273              :     {
    9274      2712774 :       result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
    9275      2712774 :       if (modifier < EXPAND_SUM)
    9276      1806405 :         result = force_operand (result, target);
    9277              :       return result;
    9278              :     }
    9279              : 
    9280              :   /* Everything must be something allowed by is_gimple_addressable.  */
    9281     11852443 :   switch (TREE_CODE (exp))
    9282              :     {
    9283           46 :     case INDIRECT_REF:
    9284              :       /* This case will happen via recursion for &a->b.  */
    9285           46 :       return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
    9286              : 
    9287       578756 :     case MEM_REF:
    9288       578756 :       {
    9289       578756 :         tree tem = TREE_OPERAND (exp, 0);
    9290       578756 :         if (!integer_zerop (TREE_OPERAND (exp, 1)))
    9291       305122 :           tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
    9292       578756 :         return expand_expr (tem, target, tmode, modifier);
    9293              :       }
    9294              : 
    9295         1277 :     case TARGET_MEM_REF:
    9296         1277 :       return addr_for_mem_ref (exp, as, true);
    9297              : 
    9298        60309 :     case CONST_DECL:
    9299              :       /* Expand the initializer like constants above.  */
    9300        60309 :       result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
    9301              :                                            0, modifier), 0);
    9302        60309 :       if (modifier < EXPAND_SUM)
    9303        60303 :         result = force_operand (result, target);
    9304              :       return result;
    9305              : 
    9306          209 :     case REALPART_EXPR:
    9307              :       /* The real part of the complex number is always first, therefore
    9308              :          the address is the same as the address of the parent object.  */
    9309          209 :       offset = 0;
    9310          209 :       bitpos = 0;
    9311          209 :       inner = TREE_OPERAND (exp, 0);
    9312          209 :       break;
    9313              : 
    9314          126 :     case IMAGPART_EXPR:
    9315              :       /* The imaginary part of the complex number is always second.
    9316              :          The expression is therefore always offset by the size of the
    9317              :          scalar type.  */
    9318          126 :       offset = 0;
    9319          252 :       bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
    9320          126 :       inner = TREE_OPERAND (exp, 0);
    9321          126 :       break;
    9322              : 
    9323           13 :     case COMPOUND_LITERAL_EXPR:
    9324              :       /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
    9325              :          initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
    9326              :          with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
    9327              :          array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
    9328              :          the initializers aren't gimplified.  */
    9329           13 :       if (COMPOUND_LITERAL_EXPR_DECL (exp)
    9330           13 :           && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
    9331           13 :         return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
    9332           13 :                                         target, tmode, modifier, as);
    9333              :       /* FALLTHRU */
    9334     11211707 :     default:
    9335              :       /* If the object is a DECL, then expand it for its rtl.  Don't bypass
    9336              :          expand_expr, as that can have various side effects; LABEL_DECLs for
    9337              :          example, may not have their DECL_RTL set yet.  Expand the rtl of
    9338              :          CONSTRUCTORs too, which should yield a memory reference for the
    9339              :          constructor's contents.  Assume language specific tree nodes can
    9340              :          be expanded in some interesting way.  */
    9341     11211707 :       gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
    9342     11211707 :       if (DECL_P (exp)
    9343      1335774 :           || TREE_CODE (exp) == CONSTRUCTOR
    9344      1335774 :           || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
    9345              :         {
    9346     16235696 :           result = expand_expr (exp, target, tmode,
    9347              :                                 modifier == EXPAND_INITIALIZER
    9348              :                                 ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
    9349              : 
    9350              :           /* If the DECL isn't in memory, then the DECL wasn't properly
    9351              :              marked TREE_ADDRESSABLE, which will be either a front-end
    9352              :              or a tree optimizer bug.  */
    9353              : 
    9354      9875933 :           gcc_assert (MEM_P (result));
    9355      9875931 :           result = XEXP (result, 0);
    9356              : 
    9357              :           /* ??? Is this needed anymore?  */
    9358      9875931 :           if (DECL_P (exp))
    9359      9875931 :             TREE_USED (exp) = 1;
    9360              : 
    9361      9875931 :           if (modifier != EXPAND_INITIALIZER
    9362              :               && modifier != EXPAND_CONST_ADDRESS
    9363      9875931 :               && modifier != EXPAND_SUM)
    9364      4306734 :             result = force_operand (result, target);
    9365              :           return result;
    9366              :         }
    9367              : 
    9368              :       /* Pass FALSE as the last argument to get_inner_reference although
    9369              :          we are expanding to RTL.  The rationale is that we know how to
    9370              :          handle "aligning nodes" here: we can just bypass them because
    9371              :          they won't change the final object whose address will be returned
    9372              :          (they actually exist only for that purpose).  */
    9373      1335774 :       inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
    9374              :                                    &unsignedp, &reversep, &volatilep);
    9375      1335774 :       break;
    9376              :     }
    9377              : 
    9378              :   /* We must have made progress.  */
    9379      1336109 :   gcc_assert (inner != exp);
    9380              : 
    9381      1336109 :   subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
    9382              :   /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
    9383              :      inner alignment, force the inner to be sufficiently aligned.  */
    9384      1336109 :   if (CONSTANT_CLASS_P (inner)
    9385      1336109 :       && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
    9386              :     {
    9387            0 :       inner = copy_node (inner);
    9388            0 :       TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
    9389            0 :       SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
    9390            0 :       TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
    9391              :     }
    9392      1336109 :   result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
    9393              : 
    9394      1336109 :   if (offset)
    9395              :     {
    9396        53368 :       rtx tmp;
    9397              : 
    9398        53368 :       if (modifier != EXPAND_NORMAL)
    9399         1655 :         result = force_operand (result, NULL);
    9400        55023 :       tmp = expand_expr (offset, NULL_RTX, tmode,
    9401              :                          modifier == EXPAND_INITIALIZER
    9402              :                           ? EXPAND_INITIALIZER : EXPAND_NORMAL);
    9403              : 
    9404              :       /* expand_expr is allowed to return an object in a mode other
    9405              :          than TMODE.  If it did, we need to convert.  */
    9406        53368 :       if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
    9407            0 :         tmp = convert_modes (tmode, GET_MODE (tmp),
    9408            0 :                              tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
    9409        53368 :       result = convert_memory_address_addr_space (tmode, result, as);
    9410        53368 :       tmp = convert_memory_address_addr_space (tmode, tmp, as);
    9411              : 
    9412        53368 :       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
    9413         1655 :         result = simplify_gen_binary (PLUS, tmode, result, tmp);
    9414              :       else
    9415              :         {
    9416        51713 :           subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
    9417        51713 :           result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
    9418              :                                         1, OPTAB_LIB_WIDEN);
    9419              :         }
    9420              :     }
    9421              : 
    9422      1336109 :   if (maybe_ne (bitpos, 0))
    9423              :     {
    9424              :       /* Someone beforehand should have rejected taking the address
    9425              :          of an object that isn't byte-aligned.  */
    9426       633353 :       poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
    9427       633353 :       result = convert_memory_address_addr_space (tmode, result, as);
    9428       633353 :       result = plus_constant (tmode, result, bytepos);
    9429       633353 :       if (modifier < EXPAND_SUM)
    9430       595850 :         result = force_operand (result, target);
    9431              :     }
    9432              : 
    9433              :   return result;
    9434              : }
    9435              : 
    9436              : /* A subroutine of expand_expr.  Evaluate EXP, which is an ADDR_EXPR.
    9437              :    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
    9438              : 
    9439              : static rtx
    9440     13229093 : expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
    9441              :                        enum expand_modifier modifier)
    9442              : {
    9443     13229093 :   addr_space_t as = ADDR_SPACE_GENERIC;
    9444     13229093 :   scalar_int_mode address_mode = Pmode;
    9445     13229093 :   scalar_int_mode pointer_mode = ptr_mode;
    9446     13229093 :   machine_mode rmode;
    9447     13229093 :   rtx result;
    9448              : 
    9449              :   /* Target mode of VOIDmode says "whatever's natural".  */
    9450     13229093 :   if (tmode == VOIDmode)
    9451     11276841 :     tmode = TYPE_MODE (TREE_TYPE (exp));
    9452              : 
    9453     13229093 :   if (POINTER_TYPE_P (TREE_TYPE (exp)))
    9454              :     {
    9455     13229093 :       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
    9456     13229093 :       address_mode = targetm.addr_space.address_mode (as);
    9457     13229093 :       pointer_mode = targetm.addr_space.pointer_mode (as);
    9458              :     }
    9459              : 
    9460              :   /* We can get called with some Weird Things if the user does silliness
    9461              :      like "(short) &a".  In that case, convert_memory_address won't do
    9462              :      the right thing, so ignore the given target mode.  */
    9463     13229093 :   scalar_int_mode new_tmode = (tmode == pointer_mode
    9464     13229093 :                                ? pointer_mode
    9465     13229093 :                                : address_mode);
    9466              : 
    9467     13229093 :   result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
    9468              :                                     new_tmode, modifier, as);
    9469              : 
    9470              :   /* Despite expand_expr claims concerning ignoring TMODE when not
    9471              :      strictly convenient, stuff breaks if we don't honor it.  Note
    9472              :      that combined with the above, we only do this for pointer modes.  */
    9473     13229091 :   rmode = GET_MODE (result);
    9474     13229091 :   if (rmode == VOIDmode)
    9475            6 :     rmode = new_tmode;
    9476     13229091 :   if (rmode != new_tmode)
    9477           74 :     result = convert_memory_address_addr_space (new_tmode, result, as);
    9478              : 
    9479     13229091 :   return result;
    9480              : }
    9481              : 
    9482              : /* Generate code for computing CONSTRUCTOR EXP.
    9483              :    An rtx for the computed value is returned.  If AVOID_TEMP_MEM
    9484              :    is TRUE, instead of creating a temporary variable in memory
    9485              :    NULL is returned and the caller needs to handle it differently.  */
    9486              : 
    9487              : static rtx
    9488       181881 : expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
    9489              :                     bool avoid_temp_mem)
    9490              : {
    9491       181881 :   tree type = TREE_TYPE (exp);
    9492       181881 :   machine_mode mode = TYPE_MODE (type);
    9493              : 
    9494              :   /* Try to avoid creating a temporary at all.  This is possible
    9495              :      if all of the initializer is zero.
    9496              :      FIXME: try to handle all [0..255] initializers we can handle
    9497              :      with memset.  */
    9498       181881 :   if (TREE_STATIC (exp)
    9499         2632 :       && !TREE_ADDRESSABLE (exp)
    9500         2632 :       && target != 0 && mode == BLKmode
    9501       182989 :       && all_zeros_p (exp))
    9502              :     {
    9503         1099 :       clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
    9504         1099 :       return target;
    9505              :     }
    9506              : 
    9507              :   /* All elts simple constants => refer to a constant in memory.  But
    9508              :      if this is a non-BLKmode mode, let it store a field at a time
    9509              :      since that should make a CONST_INT, CONST_WIDE_INT or
    9510              :      CONST_DOUBLE when we fold.  Likewise, if we have a target we can
    9511              :      use, it is best to store directly into the target unless the type
    9512              :      is large enough that memcpy will be used.  If we are making an
    9513              :      initializer and all operands are constant, put it in memory as
    9514              :      well.
    9515              : 
    9516              :      FIXME: Avoid trying to fill vector constructors piece-meal.
    9517              :      Output them with output_constant_def below unless we're sure
    9518              :      they're zeros.  This should go away when vector initializers
    9519              :      are treated like VECTOR_CST instead of arrays.  */
    9520       180782 :   if ((TREE_STATIC (exp)
    9521         1533 :        && ((mode == BLKmode
    9522           46 :             && ! (target != 0 && safe_from_p (target, exp, 1)))
    9523         1496 :            || TREE_ADDRESSABLE (exp)
    9524         1496 :            || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
    9525         1496 :                && (! can_move_by_pieces
    9526         1496 :                    (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
    9527         1496 :                     TYPE_ALIGN (type)))
    9528            4 :                && ! mostly_zeros_p (exp))))
    9529       182276 :       || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
    9530            0 :           && TREE_CONSTANT (exp)))
    9531              :     {
    9532           39 :       rtx constructor;
    9533              : 
    9534           39 :       if (avoid_temp_mem)
    9535              :         return NULL_RTX;
    9536              : 
    9537           37 :       constructor = expand_expr_constant (exp, 1, modifier);
    9538              : 
    9539           37 :       if (modifier != EXPAND_CONST_ADDRESS
    9540              :           && modifier != EXPAND_INITIALIZER
    9541           37 :           && modifier != EXPAND_SUM)
    9542           37 :         constructor = validize_mem (constructor);
    9543              : 
    9544              :       return constructor;
    9545              :     }
    9546              : 
    9547              :   /* If the CTOR is available in static storage and not mostly
    9548              :      zeros and we can move it by pieces prefer to do so since
    9549              :      that's usually more efficient than performing a series of
    9550              :      stores from immediates.  */
    9551       180743 :   if (avoid_temp_mem
    9552           97 :       && TREE_STATIC (exp)
    9553           38 :       && TREE_CONSTANT (exp)
    9554           38 :       && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
    9555           38 :       && can_move_by_pieces (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
    9556           38 :                              TYPE_ALIGN (type))
    9557       180780 :       && ! mostly_zeros_p (exp))
    9558              :     return NULL_RTX;
    9559              : 
    9560              :   /* Handle calls that pass values in multiple non-contiguous
    9561              :      locations.  The Irix 6 ABI has examples of this.  */
    9562       145256 :   if (target == 0 || ! safe_from_p (target, exp, 1)
    9563        38245 :       || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
    9564              :       /* Also make a temporary if the store is to volatile memory, to
    9565              :          avoid individual accesses to aggregate members.  */
    9566       218946 :       || (GET_CODE (target) == MEM
    9567        33728 :           && MEM_VOLATILE_P (target)
    9568          134 :           && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
    9569              :     {
    9570       142608 :       if (avoid_temp_mem)
    9571              :         return NULL_RTX;
    9572              : 
    9573       142597 :       target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
    9574              :     }
    9575              : 
    9576       180702 :   store_constructor (exp, target, 0, int_expr_size (exp), false);
    9577       180702 :   return target;
    9578              : }
    9579              : 
    9580              : 
    9581              : /* expand_expr: generate code for computing expression EXP.
    9582              :    An rtx for the computed value is returned.  The value is never null.
    9583              :    In the case of a void EXP, const0_rtx is returned.
    9584              : 
    9585              :    The value may be stored in TARGET if TARGET is nonzero.
    9586              :    TARGET is just a suggestion; callers must assume that
    9587              :    the rtx returned may not be the same as TARGET.
    9588              : 
    9589              :    If TARGET is CONST0_RTX, it means that the value will be ignored.
    9590              : 
    9591              :    If TMODE is not VOIDmode, it suggests generating the
    9592              :    result in mode TMODE.  But this is done only when convenient.
    9593              :    Otherwise, TMODE is ignored and the value generated in its natural mode.
    9594              :    TMODE is just a suggestion; callers must assume that
    9595              :    the rtx returned may not have mode TMODE.
    9596              : 
    9597              :    Note that TARGET may have neither TMODE nor MODE.  In that case, it
    9598              :    probably will not be used.
    9599              : 
    9600              :    If MODIFIER is EXPAND_SUM then when EXP is an addition
    9601              :    we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
    9602              :    or a nest of (PLUS ...) and (MINUS ...) where the terms are
    9603              :    products as above, or REG or MEM, or constant.
    9604              :    Ordinarily in such cases we would output mul or add instructions
    9605              :    and then return a pseudo reg containing the sum.
    9606              : 
    9607              :    EXPAND_INITIALIZER is much like EXPAND_SUM except that
    9608              :    it also marks a label as absolutely required (it can't be dead).
    9609              :    It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
    9610              :    This is used for outputting expressions used in initializers.
    9611              : 
    9612              :    EXPAND_CONST_ADDRESS says that it is okay to return a MEM
    9613              :    with a constant address even if that address is not normally legitimate.
    9614              :    EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
    9615              : 
    9616              :    EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
    9617              :    a call parameter.  Such targets require special care as we haven't yet
    9618              :    marked TARGET so that it's safe from being trashed by libcalls.  We
    9619              :    don't want to use TARGET for anything but the final result;
    9620              :    Intermediate values must go elsewhere.   Additionally, calls to
    9621              :    emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
    9622              : 
    9623              :    If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
    9624              :    address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
    9625              :    DECL_RTL of the VAR_DECL.  *ALT_RTL is also set if EXP is a
    9626              :    COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
    9627              :    recursively.
    9628              :    If the result can be stored at TARGET, and ALT_RTL is non-NULL,
    9629              :    then *ALT_RTL is set to TARGET (before legitimziation).
    9630              : 
    9631              :    If INNER_REFERENCE_P is true, we are expanding an inner reference.
    9632              :    In this case, we don't adjust a returned MEM rtx that wouldn't be
    9633              :    sufficiently aligned for its mode; instead, it's up to the caller
    9634              :    to deal with it afterwards.  This is used to make sure that unaligned
    9635              :    base objects for which out-of-bounds accesses are supported, for
    9636              :    example record types with trailing arrays, aren't realigned behind
    9637              :    the back of the caller.
    9638              :    The normal operating mode is to pass FALSE for this parameter.  */
    9639              : 
    9640              : rtx
    9641    159476572 : expand_expr_real (tree exp, rtx target, machine_mode tmode,
    9642              :                   enum expand_modifier modifier, rtx *alt_rtl,
    9643              :                   bool inner_reference_p)
    9644              : {
    9645    159476572 :   rtx ret;
    9646              : 
    9647              :   /* Handle ERROR_MARK before anybody tries to access its type.  */
    9648    159476572 :   if (TREE_CODE (exp) == ERROR_MARK
    9649    159476572 :       || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
    9650              :     {
    9651            0 :       ret = CONST0_RTX (tmode);
    9652            0 :       return ret ? ret : const0_rtx;
    9653              :     }
    9654              : 
    9655    159476572 :   ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
    9656              :                             inner_reference_p);
    9657    159476572 :   return ret;
    9658              : }
    9659              : 
    9660              : /* Try to expand the conditional expression which is represented by
    9661              :    TREEOP0 ? TREEOP1 : TREEOP2 using conditional moves.  If it succeeds
    9662              :    return the rtl reg which represents the result.  Otherwise return
    9663              :    NULL_RTX.  */
    9664              : 
    9665              : static rtx
    9666        17677 : expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
    9667              :                               tree treeop1 ATTRIBUTE_UNUSED,
    9668              :                               tree treeop2 ATTRIBUTE_UNUSED)
    9669              : {
    9670        17677 :   rtx insn;
    9671        17677 :   rtx op00, op01, op1, op2;
    9672        17677 :   enum rtx_code comparison_code;
    9673        17677 :   machine_mode comparison_mode;
    9674        17677 :   gimple *srcstmt;
    9675        17677 :   rtx temp;
    9676        17677 :   tree type = TREE_TYPE (treeop1);
    9677        17677 :   int unsignedp = TYPE_UNSIGNED (type);
    9678        17677 :   machine_mode mode = TYPE_MODE (type);
    9679        17677 :   machine_mode orig_mode = mode;
    9680        17677 :   static bool expanding_cond_expr_using_cmove = false;
    9681              : 
    9682              :   /* Conditional move expansion can end up TERing two operands which,
    9683              :      when recursively hitting conditional expressions can result in
    9684              :      exponential behavior if the cmove expansion ultimatively fails.
    9685              :      It's hardly profitable to TER a cmove into a cmove so avoid doing
    9686              :      that by failing early if we end up recursing.  */
    9687        17677 :   if (expanding_cond_expr_using_cmove)
    9688              :     return NULL_RTX;
    9689              : 
    9690              :   /* If we cannot do a conditional move on the mode, try doing it
    9691              :      with the promoted mode. */
    9692        17438 :   if (!can_conditionally_move_p (mode))
    9693              :     {
    9694          287 :       mode = promote_mode (type, mode, &unsignedp);
    9695          287 :       if (!can_conditionally_move_p (mode))
    9696              :         return NULL_RTX;
    9697            0 :       temp = assign_temp (type, 0, 0); /* Use promoted mode for temp.  */
    9698              :     }
    9699              :   else
    9700        17151 :     temp = assign_temp (type, 0, 1);
    9701              : 
    9702        17151 :   expanding_cond_expr_using_cmove = true;
    9703        17151 :   start_sequence ();
    9704        17151 :   expand_operands (treeop1, treeop2,
    9705              :                    mode == orig_mode ? temp : NULL_RTX, &op1, &op2,
    9706              :                    EXPAND_NORMAL);
    9707              : 
    9708        17151 :   if (TREE_CODE (treeop0) == SSA_NAME
    9709        16988 :       && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))
    9710        31889 :       && !VECTOR_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (srcstmt))))
    9711              :     {
    9712        14735 :       type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
    9713        14735 :       enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt);
    9714        14735 :       op00 = expand_normal (gimple_assign_rhs1 (srcstmt));
    9715        14735 :       op01 = expand_normal (gimple_assign_rhs2 (srcstmt));
    9716        14735 :       comparison_mode = TYPE_MODE (type);
    9717        14735 :       unsignedp = TYPE_UNSIGNED (type);
    9718        14735 :       comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
    9719              :     }
    9720         2416 :   else if (COMPARISON_CLASS_P (treeop0)
    9721         2416 :            && !VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (treeop0, 0))))
    9722              :     {
    9723          163 :       type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
    9724          163 :       enum tree_code cmpcode = TREE_CODE (treeop0);
    9725          163 :       op00 = expand_normal (TREE_OPERAND (treeop0, 0));
    9726          163 :       op01 = expand_normal (TREE_OPERAND (treeop0, 1));
    9727          163 :       unsignedp = TYPE_UNSIGNED (type);
    9728          163 :       comparison_mode = TYPE_MODE (type);
    9729          163 :       comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
    9730              :     }
    9731              :   else
    9732              :     {
    9733         2253 :       op00 = expand_normal (treeop0);
    9734         2253 :       op01 = const0_rtx;
    9735         2253 :       comparison_code = NE;
    9736         2253 :       comparison_mode = GET_MODE (op00);
    9737         2253 :       if (comparison_mode == VOIDmode)
    9738            0 :         comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
    9739              :     }
    9740        17151 :   expanding_cond_expr_using_cmove = false;
    9741              : 
    9742        17151 :   if (GET_MODE (op1) != mode)
    9743         2357 :     op1 = gen_lowpart (mode, op1);
    9744              : 
    9745        17151 :   if (GET_MODE (op2) != mode)
    9746         9123 :     op2 = gen_lowpart (mode, op2);
    9747              : 
    9748              :   /* Try to emit the conditional move.  */
    9749        17151 :   insn = emit_conditional_move (temp,
    9750              :                                 { comparison_code, op00, op01,
    9751              :                                   comparison_mode },
    9752              :                                 op1, op2, mode,
    9753              :                                 unsignedp);
    9754              : 
    9755              :   /* If we could do the conditional move, emit the sequence,
    9756              :      and return.  */
    9757        17151 :   if (insn)
    9758              :     {
    9759        14625 :       rtx_insn *seq = end_sequence ();
    9760        14625 :       emit_insn (seq);
    9761        14625 :       return convert_modes (orig_mode, mode, temp, 0);
    9762              :     }
    9763              : 
    9764              :   /* Otherwise discard the sequence and fall back to code with
    9765              :      branches.  */
    9766         2526 :   end_sequence ();
    9767         2526 :   return NULL_RTX;
    9768              : }
    9769              : 
    9770              : /* A helper function for expand_expr_real_2 to be used with a
    9771              :    misaligned mem_ref TEMP.  Assume an unsigned type if UNSIGNEDP
    9772              :    is nonzero, with alignment ALIGN in bits.
    9773              :    Store the value at TARGET if possible (if TARGET is nonzero).
    9774              :    Regardless of TARGET, we return the rtx for where the value is placed.
    9775              :    If the result can be stored at TARGET, and ALT_RTL is non-NULL,
    9776              :    then *ALT_RTL is set to TARGET (before legitimziation).  */
    9777              : 
    9778              : static rtx
    9779       214975 : expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
    9780              :                            unsigned int align, rtx target, rtx *alt_rtl)
    9781              : {
    9782       214975 :   enum insn_code icode;
    9783              : 
    9784       214975 :   if ((icode = optab_handler (movmisalign_optab, mode))
    9785              :       != CODE_FOR_nothing)
    9786              :     {
    9787       138946 :       class expand_operand ops[2];
    9788              : 
    9789              :       /* We've already validated the memory, and we're creating a
    9790              :          new pseudo destination.  The predicates really can't fail,
    9791              :          nor can the generator.  */
    9792       138946 :       create_output_operand (&ops[0], NULL_RTX, mode);
    9793       138946 :       create_fixed_operand (&ops[1], temp);
    9794       138946 :       expand_insn (icode, 2, ops);
    9795       138946 :       temp = ops[0].value;
    9796              :     }
    9797        76029 :   else if (targetm.slow_unaligned_access (mode, align))
    9798            0 :     temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
    9799              :                               0, unsignedp, target,
    9800              :                               mode, mode, false, alt_rtl);
    9801       214975 :   return temp;
    9802              : }
    9803              : 
    9804              : /* Return true if OP is known to be either LOWER or LOWER + 1, with one
    9805              :    value a positive power of two.  */
    9806              : 
    9807              : static bool
    9808        60584 : near_pow2_divisor_range_p (tree op, wide_int &lower)
    9809              : {
    9810        60584 :   if (TREE_CODE (op) != SSA_NAME)
    9811              :     return false;
    9812              : 
    9813        32177 :   int_range_max range;
    9814        32177 :   range_query *query = get_range_query (cfun);
    9815        32177 :   if (!query->range_of_expr (range, op, currently_expanding_gimple_stmt)
    9816        32177 :       || range.num_pairs () != 1)
    9817              :     return false;
    9818              : 
    9819        30173 :   lower = range.lower_bound ();
    9820        30173 :   wide_int upper = lower + 1;
    9821        60346 :   return (range.upper_bound () == upper
    9822           99 :           && wi::gt_p (lower, 0, TYPE_SIGN (TREE_TYPE (op)))
    9823        30376 :           && (wi::popcount (lower) == 1 || wi::popcount (upper) == 1));
    9824        32177 : }
    9825              : 
    9826              : /* Helper function of expand_expr_2, expand a division or modulo.
    9827              :    op0 and op1 should be already expanded treeop0 and treeop1, using
    9828              :    expand_operands.  */
    9829              : 
    9830              : static rtx
    9831       169387 : expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
    9832              :                     tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
    9833              : {
    9834       338774 :   bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
    9835       169387 :                 || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
    9836       169387 :   bool speed_p = optimize_insn_for_speed_p ();
    9837              : 
    9838       169387 :   scalar_int_mode int_mode;
    9839       169387 :   wide_int lower;
    9840              :   /* Split x / y when y is one of two neighboring constants and the target can
    9841              :      select between the constant divisions cheaply.  */
    9842       169387 :   if (code == TRUNC_DIV_EXPR
    9843       235121 :       && is_a <scalar_int_mode> (mode, &int_mode)
    9844        65807 :       && speed_p
    9845        63194 :       && can_conditionally_move_p (int_mode)
    9846       229971 :       && near_pow2_divisor_range_p (treeop1, lower))
    9847              :     {
    9848           73 :       signop sgn = TYPE_SIGN (TREE_TYPE (treeop1));
    9849           73 :       unsigned int prec = GET_MODE_PRECISION (int_mode);
    9850           73 :       wide_int upper = lower + 1;
    9851           73 :       rtx op_lower
    9852           73 :         = immed_wide_int_const (wide_int::from (lower, prec, sgn), int_mode);
    9853           73 :       rtx op_upper
    9854           73 :         = immed_wide_int_const (wide_int::from (upper, prec, sgn), int_mode);
    9855              : 
    9856           73 :       do_pending_stack_adjust ();
    9857           73 :       start_sequence ();
    9858           73 :       rtx q_lower = expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op_lower,
    9859              :                                    NULL_RTX, unsignedp);
    9860           73 :       rtx q_upper = expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op_upper,
    9861              :                                    NULL_RTX, unsignedp);
    9862           73 :       rtx split_ret
    9863           73 :         = emit_conditional_move (target, { EQ, op1, op_lower, int_mode },
    9864              :                                  q_lower, q_upper, int_mode, unsignedp);
    9865           73 :       rtx_insn *split_insns = end_sequence ();
    9866              : 
    9867              :       /* Cost the unsplit form as a single DIV/UDIV.  */
    9868           73 :       rtx div_rtx = gen_rtx_fmt_ee (unsignedp ? UDIV : DIV, int_mode, op0, op1);
    9869           73 :       unsigned div_cost = set_src_cost (div_rtx, int_mode, speed_p);
    9870           73 :       if (split_ret && seq_cost (split_insns, speed_p) < div_cost)
    9871              :         {
    9872           73 :           emit_insn (split_insns);
    9873           73 :           return split_ret;
    9874              :         }
    9875           73 :     }
    9876              : 
    9877       169314 :   if (SCALAR_INT_MODE_P (mode)
    9878       169314 :       && optimize >= 2
    9879       141966 :       && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1
    9880       212875 :       && get_range_pos_neg (treeop1, currently_expanding_gimple_stmt) == 1)
    9881              :     {
    9882              :       /* If both arguments are known to be positive when interpreted
    9883              :          as signed, we can expand it as both signed and unsigned
    9884              :          division or modulo.  Choose the cheaper sequence in that case.  */
    9885        13990 :       do_pending_stack_adjust ();
    9886        13990 :       start_sequence ();
    9887        13990 :       rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
    9888        13990 :       rtx_insn *uns_insns = end_sequence ();
    9889        13990 :       start_sequence ();
    9890        13990 :       rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
    9891        13990 :       rtx_insn *sgn_insns = end_sequence ();
    9892        13990 :       unsigned uns_cost = seq_cost (uns_insns, speed_p);
    9893        13990 :       unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
    9894        13990 :       bool was_tie = false;
    9895              : 
    9896              :       /* If costs are the same then use as tie breaker the other other
    9897              :          factor.  */
    9898        13990 :       if (uns_cost == sgn_cost)
    9899              :         {
    9900         3592 :           uns_cost = seq_cost (uns_insns, !speed_p);
    9901         3592 :           sgn_cost = seq_cost (sgn_insns, !speed_p);
    9902         3592 :           was_tie = true;
    9903              :         }
    9904              : 
    9905        13990 :       if (dump_file && (dump_flags & TDF_DETAILS))
    9906            0 :         fprintf (dump_file, ";; positive division:%s unsigned cost: %u; "
    9907              :                             "signed cost: %u\n",
    9908              :                  was_tie ? " (needed tie breaker)" : "", uns_cost, sgn_cost);
    9909              : 
    9910        13990 :       if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
    9911              :         {
    9912        11270 :           emit_insn (uns_insns);
    9913        11270 :           return uns_ret;
    9914              :         }
    9915         2720 :       emit_insn (sgn_insns);
    9916         2720 :       return sgn_ret;
    9917              :     }
    9918       155324 :   return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
    9919       169387 : }
    9920              : 
    9921              : /* Return true if EXP has a range of values [0..1], false
    9922              :    otherwise. This works for constants and ssa names, calling back into the ranger.  */
    9923              : static bool
    9924      1522240 : expr_has_boolean_range (tree exp, gimple *stmt)
    9925              : {
    9926              :   /* An integral type with a single bit of precision.  */
    9927      3044467 :   if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
    9928      1522240 :       && TYPE_UNSIGNED (TREE_TYPE (exp))
    9929      2527798 :       && TYPE_PRECISION (TREE_TYPE (exp)) == 1)
    9930              :     return true;
    9931              : 
    9932              :   /* Signed 1 bit integers are not boolean ranges. */
    9933      3044467 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
    9934      3044467 :       || TYPE_PRECISION (TREE_TYPE (exp)) <= 1)
    9935              :     return false;
    9936              : 
    9937      1522196 :   if (TREE_CODE (exp) == SSA_NAME)
    9938       905738 :     return ssa_name_has_boolean_range (exp, stmt);
    9939       616458 :   if (TREE_CODE (exp) == INTEGER_CST)
    9940       544975 :     return wi::leu_p (wi::to_wide (exp), 1);
    9941              :   return false;
    9942              : }
    9943              : 
    9944              : rtx
    9945     13655602 : expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
    9946              :                     enum expand_modifier modifier)
    9947              : {
    9948     13655602 :   rtx op0, op1, op2, temp;
    9949     13655602 :   rtx_code_label *lab;
    9950     13655602 :   tree type;
    9951     13655602 :   int unsignedp;
    9952     13655602 :   machine_mode mode;
    9953     13655602 :   scalar_int_mode int_mode;
    9954     13655602 :   enum tree_code code = ops->code;
    9955     13655602 :   optab this_optab;
    9956     13655602 :   rtx subtarget, original_target;
    9957     13655602 :   int ignore;
    9958     13655602 :   bool reduce_bit_field;
    9959     13655602 :   location_t loc = ops->location;
    9960     13655602 :   tree treeop0, treeop1, treeop2;
    9961              : #define REDUCE_BIT_FIELD(expr)  (reduce_bit_field                         \
    9962              :                                  ? reduce_to_bit_field_precision ((expr), \
    9963              :                                                                   target, \
    9964              :                                                                   type)   \
    9965              :                                  : (expr))
    9966              : 
    9967     13655602 :   type = ops->type;
    9968     13655602 :   mode = TYPE_MODE (type);
    9969     13655602 :   unsignedp = TYPE_UNSIGNED (type);
    9970              : 
    9971     13655602 :   treeop0 = ops->op0;
    9972     13655602 :   treeop1 = ops->op1;
    9973     13655602 :   treeop2 = ops->op2;
    9974              : 
    9975              :   /* We should be called only on simple (binary or unary) expressions,
    9976              :      exactly those that are valid in gimple expressions that aren't
    9977              :      GIMPLE_SINGLE_RHS (or invalid).  */
    9978     13655602 :   gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
    9979              :               || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
    9980              :               || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
    9981              : 
    9982     27311204 :   ignore = (target == const0_rtx
    9983     13655602 :             || ((CONVERT_EXPR_CODE_P (code)
    9984      9815787 :                  || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
    9985      3857492 :                 && TREE_CODE (type) == VOID_TYPE));
    9986              : 
    9987              :   /* We should be called only if we need the result.  */
    9988            0 :   gcc_assert (!ignore);
    9989              : 
    9990              :   /* An operation in what may be a bit-field type needs the
    9991              :      result to be reduced to the precision of the bit-field type,
    9992              :      which is narrower than that of the type's mode.  */
    9993     28139103 :   reduce_bit_field = (INTEGRAL_TYPE_P (type)
    9994     13655602 :                       && !type_has_mode_precision_p (type));
    9995              : 
    9996       827899 :   if (reduce_bit_field
    9997       827899 :       && (modifier == EXPAND_STACK_PARM
    9998       827374 :           || (target && GET_MODE (target) != mode)))
    9999       514486 :     target = 0;
   10000              : 
   10001              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
   10002     13655602 :   subtarget = get_subtarget (target);
   10003     13655602 :   original_target = target;
   10004              : 
   10005     13655602 :   switch (code)
   10006              :     {
   10007      3844003 :     case NON_LVALUE_EXPR:
   10008      3844003 :     case PAREN_EXPR:
   10009      3844003 :     CASE_CONVERT:
   10010      3844003 :       if (treeop0 == error_mark_node)
   10011            0 :         return const0_rtx;
   10012              : 
   10013      3844003 :       if (TREE_CODE (type) == UNION_TYPE)
   10014              :         {
   10015            0 :           tree valtype = TREE_TYPE (treeop0);
   10016              : 
   10017              :           /* If both input and output are BLKmode, this conversion isn't doing
   10018              :              anything except possibly changing memory attribute.  */
   10019            0 :           if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
   10020              :             {
   10021            0 :               rtx result = expand_expr (treeop0, target, tmode,
   10022              :                                         modifier);
   10023              : 
   10024            0 :               result = copy_rtx (result);
   10025            0 :               set_mem_attributes (result, type, 0);
   10026            0 :               return result;
   10027              :             }
   10028              : 
   10029            0 :           if (target == 0)
   10030              :             {
   10031            0 :               if (TYPE_MODE (type) != BLKmode)
   10032            0 :                 target = gen_reg_rtx (TYPE_MODE (type));
   10033              :               else
   10034            0 :                 target = assign_temp (type, 1, 1);
   10035              :             }
   10036              : 
   10037            0 :           if (MEM_P (target))
   10038              :             /* Store data into beginning of memory target.  */
   10039            0 :             store_expr (treeop0,
   10040            0 :                         adjust_address (target, TYPE_MODE (valtype), 0),
   10041              :                         modifier == EXPAND_STACK_PARM,
   10042            0 :                         false, TYPE_REVERSE_STORAGE_ORDER (type));
   10043              : 
   10044              :           else
   10045              :             {
   10046            0 :               gcc_assert (REG_P (target)
   10047              :                           && !TYPE_REVERSE_STORAGE_ORDER (type));
   10048              : 
   10049              :               /* Store this field into a union of the proper type.  */
   10050            0 :               poly_uint64 op0_size
   10051            0 :                 = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
   10052            0 :               poly_uint64 union_size = GET_MODE_BITSIZE (mode);
   10053            0 :               store_field (target,
   10054              :                            /* The conversion must be constructed so that
   10055              :                               we know at compile time how many bits
   10056              :                               to preserve.  */
   10057            0 :                            ordered_min (op0_size, union_size),
   10058            0 :                            0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
   10059              :                            false, false);
   10060              :             }
   10061              : 
   10062              :           /* Return the entire union.  */
   10063              :           return target;
   10064              :         }
   10065              : 
   10066      3844003 :       if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
   10067              :         {
   10068      2287065 :           op0 = expand_expr (treeop0, target, VOIDmode,
   10069              :                              modifier);
   10070              : 
   10071      2287065 :           return REDUCE_BIT_FIELD (op0);
   10072              :         }
   10073              : 
   10074      1921205 :       op0 = expand_expr (treeop0, NULL_RTX, mode,
   10075              :                          modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
   10076      1556938 :       if (GET_MODE (op0) == mode)
   10077              :         ;
   10078              : 
   10079              :       /* If OP0 is a constant, just convert it into the proper mode.  */
   10080      1513549 :       else if (CONSTANT_P (op0))
   10081              :         {
   10082          902 :           tree inner_type = TREE_TYPE (treeop0);
   10083          902 :           machine_mode inner_mode = GET_MODE (op0);
   10084              : 
   10085          902 :           if (inner_mode == VOIDmode)
   10086           15 :             inner_mode = TYPE_MODE (inner_type);
   10087              : 
   10088          902 :           if (modifier == EXPAND_INITIALIZER)
   10089            0 :             op0 = force_lowpart_subreg (mode, op0, inner_mode);
   10090              :           else
   10091          902 :             op0 = convert_modes (mode, inner_mode, op0,
   10092          902 :                                  TYPE_UNSIGNED (inner_type));
   10093              :         }
   10094              : 
   10095      1512647 :       else if (modifier == EXPAND_INITIALIZER)
   10096           24 :         op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
   10097              :                              ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
   10098              : 
   10099      1512635 :       else if (SCALAR_INT_MODE_P (GET_MODE (op0))
   10100      1336792 :                && optimize >= 2
   10101       782899 :                && SCALAR_INT_MODE_P (mode)
   10102       782899 :                && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
   10103       782735 :                && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
   10104      1565470 :                    > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
   10105      2062566 :                && get_range_pos_neg (treeop0,
   10106              :                                      currently_expanding_gimple_stmt) == 1)
   10107              :         {
   10108              :           /* If argument is known to be positive when interpreted
   10109              :              as signed, we can expand it as both sign and zero
   10110              :              extension.  Choose the cheaper sequence in that case.  */
   10111       139700 :           bool speed_p = optimize_insn_for_speed_p ();
   10112       139700 :           rtx uns_ret = NULL_RTX, sgn_ret = NULL_RTX;
   10113       139700 :           do_pending_stack_adjust ();
   10114       139700 :           start_sequence ();
   10115       139700 :           if (target == NULL_RTX)
   10116       115535 :             uns_ret = convert_to_mode (mode, op0, 1);
   10117              :           else
   10118        24165 :             convert_move (target, op0, 1);
   10119       139700 :           rtx_insn *uns_insns = end_sequence ();
   10120       139700 :           start_sequence ();
   10121       139700 :           if (target == NULL_RTX)
   10122       115535 :             sgn_ret = convert_to_mode (mode, op0, 0);
   10123              :           else
   10124        24165 :             convert_move (target, op0, 0);
   10125       139700 :           rtx_insn *sgn_insns = end_sequence ();
   10126       139700 :           unsigned uns_cost = seq_cost (uns_insns, speed_p);
   10127       139700 :           unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
   10128       139700 :           bool was_tie = false;
   10129              : 
   10130              :           /* If costs are the same then use as tie breaker the other other
   10131              :              factor.  */
   10132       139700 :           if (uns_cost == sgn_cost)
   10133              :             {
   10134        38641 :               uns_cost = seq_cost (uns_insns, !speed_p);
   10135        38641 :               sgn_cost = seq_cost (sgn_insns, !speed_p);
   10136        38641 :               was_tie = true;
   10137              :             }
   10138              : 
   10139       139700 :           if (dump_file && (dump_flags & TDF_DETAILS))
   10140            0 :             fprintf (dump_file, ";; positive extension:%s unsigned cost: %u; "
   10141              :                                 "signed cost: %u\n",
   10142              :                      was_tie ? " (needed tie breaker)" : "",
   10143              :                      uns_cost, sgn_cost);
   10144       139700 :           if (uns_cost < sgn_cost
   10145       139700 :               || (uns_cost == sgn_cost && TYPE_UNSIGNED (TREE_TYPE (treeop0))))
   10146              :             {
   10147       124716 :               emit_insn (uns_insns);
   10148       124716 :               sgn_ret = uns_ret;
   10149              :             }
   10150              :           else
   10151        14984 :             emit_insn (sgn_insns);
   10152       139700 :           if (target == NULL_RTX)
   10153       115535 :             op0 = sgn_ret;
   10154              :           else
   10155        24165 :             op0 = target;
   10156              :         }
   10157      1372935 :       else if (target == 0)
   10158       861724 :         op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10159              :       else
   10160              :         {
   10161       511211 :           convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10162       511211 :           op0 = target;
   10163              :         }
   10164              : 
   10165      1556938 :       return REDUCE_BIT_FIELD (op0);
   10166              : 
   10167            0 :     case ADDR_SPACE_CONVERT_EXPR:
   10168            0 :       {
   10169            0 :         tree treeop0_type = TREE_TYPE (treeop0);
   10170              : 
   10171            0 :         gcc_assert (POINTER_TYPE_P (type));
   10172            0 :         gcc_assert (POINTER_TYPE_P (treeop0_type));
   10173              : 
   10174            0 :         addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
   10175            0 :         addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
   10176              : 
   10177              :         /* Conversions between pointers to the same address space should
   10178              :            have been implemented via CONVERT_EXPR / NOP_EXPR.  */
   10179            0 :         gcc_assert (as_to != as_from);
   10180              : 
   10181            0 :         op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
   10182              : 
   10183              :         /* Ask target code to handle conversion between pointers
   10184              :            to overlapping address spaces.  */
   10185            0 :         if (targetm.addr_space.subset_p (as_to, as_from)
   10186            0 :             || targetm.addr_space.subset_p (as_from, as_to))
   10187              :           {
   10188            0 :             op0 = targetm.addr_space.convert (op0, treeop0_type, type);
   10189              :           }
   10190              :         else
   10191              :           {
   10192              :             /* For disjoint address spaces, converting anything but a null
   10193              :                pointer invokes undefined behavior.  We truncate or extend the
   10194              :                value as if we'd converted via integers, which handles 0 as
   10195              :                required, and all others as the programmer likely expects.  */
   10196              : #ifndef POINTERS_EXTEND_UNSIGNED
   10197              :             const int POINTERS_EXTEND_UNSIGNED = 1;
   10198              : #endif
   10199            0 :             op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
   10200              :                                  op0, POINTERS_EXTEND_UNSIGNED);
   10201              :           }
   10202            0 :         gcc_assert (op0);
   10203              :         return op0;
   10204              :       }
   10205              : 
   10206      1376395 :     case POINTER_PLUS_EXPR:
   10207              :       /* Even though the sizetype mode and the pointer's mode can be different
   10208              :          expand is able to handle this correctly and get the correct result out
   10209              :          of the PLUS_EXPR code.  */
   10210              :       /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
   10211              :          if sizetype precision is smaller than pointer precision.  */
   10212      1376395 :       if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
   10213            0 :         treeop1 = fold_convert_loc (loc, type,
   10214              :                                     fold_convert_loc (loc, ssizetype,
   10215              :                                                       treeop1));
   10216              :       /* If sizetype precision is larger than pointer precision, truncate the
   10217              :          offset to have matching modes.  */
   10218      1376395 :       else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
   10219            0 :         treeop1 = fold_convert_loc (loc, type, treeop1);
   10220              :       /* FALLTHRU */
   10221              : 
   10222      5399032 :     case PLUS_EXPR:
   10223              :       /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
   10224              :          something else, make sure we add the register to the constant and
   10225              :          then to the other thing.  This case can occur during strength
   10226              :          reduction and doing it this way will produce better code if the
   10227              :          frame pointer or argument pointer is eliminated.
   10228              : 
   10229              :          fold-const.cc will ensure that the constant is always in the inner
   10230              :          PLUS_EXPR, so the only case we need to do anything about is if
   10231              :          sp, ap, or fp is our second argument, in which case we must swap
   10232              :          the innermost first argument and our second argument.  */
   10233              : 
   10234      5399032 :       if (TREE_CODE (treeop0) == PLUS_EXPR
   10235         6600 :           && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
   10236            0 :           && VAR_P (treeop1)
   10237      5399032 :           && (DECL_RTL (treeop1) == frame_pointer_rtx
   10238            0 :               || DECL_RTL (treeop1) == stack_pointer_rtx
   10239            0 :               || DECL_RTL (treeop1) == arg_pointer_rtx))
   10240              :         {
   10241            0 :           gcc_unreachable ();
   10242              :         }
   10243              : 
   10244              :       /* If the result is to be ptr_mode and we are adding an integer to
   10245              :          something, we might be forming a constant.  So try to use
   10246              :          plus_constant.  If it produces a sum and we can't accept it,
   10247              :          use force_operand.  This allows P = &ARR[const] to generate
   10248              :          efficient code on machines where a SYMBOL_REF is not a valid
   10249              :          address.
   10250              : 
   10251              :          If this is an EXPAND_SUM call, always return the sum.  */
   10252      5399032 :       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
   10253      5399032 :           || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
   10254              :         {
   10255      3523749 :           if (modifier == EXPAND_STACK_PARM)
   10256        18844 :             target = 0;
   10257      3523749 :           if (TREE_CODE (treeop0) == INTEGER_CST
   10258      3524756 :               && HWI_COMPUTABLE_MODE_P (mode)
   10259      3524760 :               && TREE_CONSTANT (treeop1))
   10260              :             {
   10261            4 :               rtx constant_part;
   10262            4 :               HOST_WIDE_INT wc;
   10263            4 :               machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
   10264              : 
   10265            4 :               op1 = expand_expr (treeop1, subtarget, VOIDmode,
   10266              :                                  EXPAND_SUM);
   10267              :               /* Use wi::shwi to ensure that the constant is
   10268              :                  truncated according to the mode of OP1, then sign extended
   10269              :                  to a HOST_WIDE_INT.  Using the constant directly can result
   10270              :                  in non-canonical RTL in a 64x32 cross compile.  */
   10271            4 :               wc = TREE_INT_CST_LOW (treeop0);
   10272            4 :               constant_part =
   10273            4 :                 immed_wide_int_const (wi::shwi (wc, wmode), wmode);
   10274            4 :               op1 = plus_constant (mode, op1, INTVAL (constant_part));
   10275            4 :               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
   10276            1 :                 op1 = force_operand (op1, target);
   10277            4 :               return REDUCE_BIT_FIELD (op1);
   10278              :             }
   10279              : 
   10280      3523745 :           else if (TREE_CODE (treeop1) == INTEGER_CST
   10281      7507906 :                    && HWI_COMPUTABLE_MODE_P (mode)
   10282      5914564 :                    && TREE_CONSTANT (treeop0))
   10283              :             {
   10284       281941 :               rtx constant_part;
   10285       281941 :               HOST_WIDE_INT wc;
   10286       281941 :               machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
   10287              : 
   10288       492063 :               op0 = expand_expr (treeop0, subtarget, VOIDmode,
   10289              :                                  (modifier == EXPAND_INITIALIZER
   10290              :                                  ? EXPAND_INITIALIZER : EXPAND_SUM));
   10291       281941 :               if (! CONSTANT_P (op0))
   10292              :                 {
   10293            6 :                   op1 = expand_expr (treeop1, NULL_RTX,
   10294              :                                      VOIDmode, modifier);
   10295              :                   /* Return a PLUS if modifier says it's OK.  */
   10296            6 :                   if (modifier == EXPAND_SUM
   10297              :                       || modifier == EXPAND_INITIALIZER)
   10298            6 :                     return simplify_gen_binary (PLUS, mode, op0, op1);
   10299            0 :                   goto binop2;
   10300              :                 }
   10301              :               /* Use wi::shwi to ensure that the constant is
   10302              :                  truncated according to the mode of OP1, then sign extended
   10303              :                  to a HOST_WIDE_INT.  Using the constant directly can result
   10304              :                  in non-canonical RTL in a 64x32 cross compile.  */
   10305       281935 :               wc = TREE_INT_CST_LOW (treeop1);
   10306       281935 :               constant_part
   10307       281935 :                 = immed_wide_int_const (wi::shwi (wc, wmode), wmode);
   10308       281935 :               op0 = plus_constant (mode, op0, INTVAL (constant_part));
   10309       281935 :               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
   10310       209291 :                 op0 = force_operand (op0, target);
   10311       281935 :               return REDUCE_BIT_FIELD (op0);
   10312              :             }
   10313              :         }
   10314              : 
   10315              :       /* Use TER to expand pointer addition of a negated value
   10316              :          as pointer subtraction.  */
   10317      9159178 :       if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
   10318      4022624 :            || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
   10319        82919 :                && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
   10320      1094463 :           && TREE_CODE (treeop1) == SSA_NAME
   10321      6257541 :           && TYPE_MODE (TREE_TYPE (treeop0))
   10322       570227 :              == TYPE_MODE (TREE_TYPE (treeop1)))
   10323              :         {
   10324       570227 :           gimple *def = get_def_for_expr (treeop1, NEGATE_EXPR);
   10325       570227 :           if (def)
   10326              :             {
   10327         2181 :               treeop1 = gimple_assign_rhs1 (def);
   10328         2181 :               code = MINUS_EXPR;
   10329         2181 :               goto do_minus;
   10330              :             }
   10331              :         }
   10332              : 
   10333              :       /* No sense saving up arithmetic to be done
   10334              :          if it's all in the wrong mode to form part of an address.
   10335              :          And force_operand won't know whether to sign-extend or
   10336              :          zero-extend.  */
   10337      5114906 :       if (modifier != EXPAND_INITIALIZER
   10338      5114906 :           && (modifier != EXPAND_SUM || mode != ptr_mode))
   10339              :         {
   10340      4538239 :           expand_operands (treeop0, treeop1,
   10341              :                            subtarget, &op0, &op1, modifier);
   10342      4538239 :           if (op0 == const0_rtx)
   10343         8994 :             return op1;
   10344      4529245 :           if (op1 == const0_rtx)
   10345              :             return op0;
   10346      4528994 :           goto binop2;
   10347              :         }
   10348              : 
   10349       576667 :       expand_operands (treeop0, treeop1,
   10350              :                        subtarget, &op0, &op1, modifier);
   10351       576667 :       return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
   10352              : 
   10353       544810 :     case MINUS_EXPR:
   10354       544810 :     case POINTER_DIFF_EXPR:
   10355       544810 :     do_minus:
   10356              :       /* For initializers, we are allowed to return a MINUS of two
   10357              :          symbolic constants.  Here we handle all cases when both operands
   10358              :          are constant.  */
   10359              :       /* Handle difference of two symbolic constants,
   10360              :          for the sake of an initializer.  */
   10361       544810 :       if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
   10362         2546 :           && really_constant_p (treeop0)
   10363       545322 :           && really_constant_p (treeop1))
   10364              :         {
   10365           68 :           expand_operands (treeop0, treeop1,
   10366              :                            NULL_RTX, &op0, &op1, modifier);
   10367           68 :           return simplify_gen_binary (MINUS, mode, op0, op1);
   10368              :         }
   10369              : 
   10370              :       /* No sense saving up arithmetic to be done
   10371              :          if it's all in the wrong mode to form part of an address.
   10372              :          And force_operand won't know whether to sign-extend or
   10373              :          zero-extend.  */
   10374       544742 :       if (modifier != EXPAND_INITIALIZER
   10375       544742 :           && (modifier != EXPAND_SUM || mode != ptr_mode))
   10376       542264 :         goto binop;
   10377              : 
   10378         2478 :       expand_operands (treeop0, treeop1,
   10379              :                        subtarget, &op0, &op1, modifier);
   10380              : 
   10381              :       /* Convert A - const to A + (-const).  */
   10382         2478 :       if (CONST_INT_P (op1))
   10383              :         {
   10384            0 :           op1 = negate_rtx (mode, op1);
   10385            0 :           return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
   10386              :         }
   10387              : 
   10388         2478 :       goto binop2;
   10389              : 
   10390            0 :     case WIDEN_MULT_PLUS_EXPR:
   10391            0 :     case WIDEN_MULT_MINUS_EXPR:
   10392            0 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   10393            0 :       op2 = expand_normal (treeop2);
   10394            0 :       target = expand_widen_pattern_expr (ops, op0, op1, op2,
   10395              :                                           target, unsignedp);
   10396            0 :       return target;
   10397              : 
   10398        24439 :     case WIDEN_MULT_EXPR:
   10399              :       /* If first operand is constant, swap them.
   10400              :          Thus the following special case checks need only
   10401              :          check the second operand.  */
   10402        24439 :       if (TREE_CODE (treeop0) == INTEGER_CST)
   10403          368 :         std::swap (treeop0, treeop1);
   10404              : 
   10405              :       /* First, check if we have a multiplication of one signed and one
   10406              :          unsigned operand.  */
   10407        24439 :       if (TREE_CODE (treeop1) != INTEGER_CST
   10408        24439 :           && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
   10409        18654 :               != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
   10410              :         {
   10411            0 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
   10412            0 :           this_optab = usmul_widen_optab;
   10413            0 :           if (find_widening_optab_handler (this_optab, mode, innermode)
   10414              :                 != CODE_FOR_nothing)
   10415              :             {
   10416            0 :               if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10417            0 :                 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
   10418              :                                  EXPAND_NORMAL);
   10419              :               else
   10420            0 :                 expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
   10421              :                                  EXPAND_NORMAL);
   10422              :               /* op0 and op1 might still be constant, despite the above
   10423              :                  != INTEGER_CST check.  Handle it.  */
   10424            0 :               if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10425              :                 {
   10426            0 :                   op0 = convert_modes (mode, innermode, op0, true);
   10427            0 :                   op1 = convert_modes (mode, innermode, op1, false);
   10428            0 :                   return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
   10429              :                                                         target, unsignedp));
   10430              :                 }
   10431            0 :               goto binop3;
   10432              :             }
   10433              :         }
   10434              :       /* Check for a multiplication with matching signedness.  */
   10435        24439 :       else if ((TREE_CODE (treeop1) == INTEGER_CST
   10436         5785 :                 && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
   10437        24443 :                || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
   10438        18658 :                    == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
   10439              :         {
   10440        24439 :           tree op0type = TREE_TYPE (treeop0);
   10441        24439 :           machine_mode innermode = TYPE_MODE (op0type);
   10442        24439 :           bool zextend_p = TYPE_UNSIGNED (op0type);
   10443        24439 :           optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
   10444         2577 :           this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
   10445              : 
   10446        24439 :           if (TREE_CODE (treeop0) != INTEGER_CST)
   10447              :             {
   10448        24439 :               if (find_widening_optab_handler (this_optab, mode, innermode)
   10449              :                   != CODE_FOR_nothing)
   10450              :                 {
   10451        24439 :                   expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
   10452              :                                    EXPAND_NORMAL);
   10453              :                   /* op0 and op1 might still be constant, despite the above
   10454              :                      != INTEGER_CST check.  Handle it.  */
   10455        24439 :                   if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10456              :                     {
   10457            0 :                      widen_mult_const:
   10458            0 :                       op0 = convert_modes (mode, innermode, op0, zextend_p);
   10459            0 :                       op1
   10460            0 :                         = convert_modes (mode, innermode, op1,
   10461            0 :                                          TYPE_UNSIGNED (TREE_TYPE (treeop1)));
   10462            0 :                       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
   10463              :                                                             target,
   10464              :                                                             unsignedp));
   10465              :                     }
   10466        24439 :                   temp = expand_widening_mult (mode, op0, op1, target,
   10467              :                                                unsignedp, this_optab);
   10468        24439 :                   return REDUCE_BIT_FIELD (temp);
   10469              :                 }
   10470            0 :               if (find_widening_optab_handler (other_optab, mode, innermode)
   10471              :                   != CODE_FOR_nothing
   10472            0 :                   && innermode == word_mode)
   10473              :                 {
   10474            0 :                   rtx htem, hipart;
   10475            0 :                   op0 = expand_normal (treeop0);
   10476            0 :                   op1 = expand_normal (treeop1);
   10477              :                   /* op0 and op1 might be constants, despite the above
   10478              :                      != INTEGER_CST check.  Handle it.  */
   10479            0 :                   if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
   10480            0 :                     goto widen_mult_const;
   10481            0 :                   temp = expand_binop (mode, other_optab, op0, op1, target,
   10482              :                                        unsignedp, OPTAB_LIB_WIDEN);
   10483            0 :                   hipart = gen_highpart (word_mode, temp);
   10484            0 :                   htem = expand_mult_highpart_adjust (word_mode, hipart,
   10485              :                                                       op0, op1, hipart,
   10486              :                                                       zextend_p);
   10487            0 :                   if (htem != hipart)
   10488            0 :                     emit_move_insn (hipart, htem);
   10489            0 :                   return REDUCE_BIT_FIELD (temp);
   10490              :                 }
   10491              :             }
   10492              :         }
   10493            0 :       treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
   10494            0 :       treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
   10495            0 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10496            0 :       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
   10497              : 
   10498      1426451 :     case MULT_EXPR:
   10499              :       /* If this is a fixed-point operation, then we cannot use the code
   10500              :          below because "expand_mult" doesn't support sat/no-sat fixed-point
   10501              :          multiplications.   */
   10502      1426451 :       if (ALL_FIXED_POINT_MODE_P (mode))
   10503            0 :         goto binop;
   10504              : 
   10505              :       /* If first operand is constant, swap them.
   10506              :          Thus the following special case checks need only
   10507              :          check the second operand.  */
   10508      1426451 :       if (TREE_CODE (treeop0) == INTEGER_CST)
   10509          686 :         std::swap (treeop0, treeop1);
   10510              : 
   10511              :       /* Attempt to return something suitable for generating an
   10512              :          indexed address, for machines that support that.  */
   10513              : 
   10514       538584 :       if (modifier == EXPAND_SUM && mode == ptr_mode
   10515      1965035 :           && tree_fits_shwi_p (treeop1))
   10516              :         {
   10517       531511 :           tree exp1 = treeop1;
   10518              : 
   10519       531511 :           op0 = expand_expr (treeop0, subtarget, VOIDmode,
   10520              :                              EXPAND_SUM);
   10521              : 
   10522       531511 :           if (!REG_P (op0))
   10523       244848 :             op0 = force_operand (op0, NULL_RTX);
   10524       531511 :           if (!REG_P (op0))
   10525         2377 :             op0 = copy_to_mode_reg (mode, op0);
   10526              : 
   10527       531511 :           op1 = gen_int_mode (tree_to_shwi (exp1),
   10528       531511 :                               TYPE_MODE (TREE_TYPE (exp1)));
   10529       531511 :           return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
   10530              :         }
   10531              : 
   10532       894940 :       if (modifier == EXPAND_STACK_PARM)
   10533         2914 :         target = 0;
   10534              : 
   10535       894940 :       if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
   10536              :         {
   10537       541137 :           gimple *def_stmt0 = get_def_for_expr (treeop0, TRUNC_DIV_EXPR);
   10538       541137 :           gimple *def_stmt1 = get_def_for_expr (treeop1, TRUNC_DIV_EXPR);
   10539       541137 :           if (def_stmt0
   10540       541137 :               && !operand_equal_p (treeop1, gimple_assign_rhs2 (def_stmt0), 0))
   10541              :             def_stmt0 = NULL;
   10542       541137 :           if (def_stmt1
   10543       541137 :               && !operand_equal_p (treeop0, gimple_assign_rhs2 (def_stmt1), 0))
   10544              :             def_stmt1 = NULL;
   10545              : 
   10546       541137 :           if (def_stmt0 || def_stmt1)
   10547              :             {
   10548              :               /* X / Y * Y can be expanded as X - X % Y too.
   10549              :                  Choose the cheaper sequence of those two.  */
   10550          194 :               if (def_stmt0)
   10551          194 :                 treeop0 = gimple_assign_rhs1 (def_stmt0);
   10552              :               else
   10553              :                 {
   10554            0 :                   treeop1 = treeop0;
   10555            0 :                   treeop0 = gimple_assign_rhs1 (def_stmt1);
   10556              :                 }
   10557          194 :               expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
   10558              :                                EXPAND_NORMAL);
   10559          194 :               bool speed_p = optimize_insn_for_speed_p ();
   10560          194 :               do_pending_stack_adjust ();
   10561          194 :               start_sequence ();
   10562          194 :               rtx divmul_ret
   10563          194 :                 = expand_expr_divmod (TRUNC_DIV_EXPR, mode, treeop0, treeop1,
   10564              :                                       op0, op1, NULL_RTX, unsignedp);
   10565          194 :               divmul_ret = expand_mult (mode, divmul_ret, op1, target,
   10566              :                                         unsignedp);
   10567          194 :               rtx_insn *divmul_insns = end_sequence ();
   10568          194 :               start_sequence ();
   10569          194 :               rtx modsub_ret
   10570          194 :                 = expand_expr_divmod (TRUNC_MOD_EXPR, mode, treeop0, treeop1,
   10571              :                                       op0, op1, NULL_RTX, unsignedp);
   10572          194 :               this_optab = optab_for_tree_code (MINUS_EXPR, type,
   10573              :                                                 optab_default);
   10574          194 :               modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
   10575              :                                          target, unsignedp, OPTAB_LIB_WIDEN);
   10576          194 :               rtx_insn *modsub_insns = end_sequence ();
   10577          194 :               unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
   10578          194 :               unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
   10579              :               /* If costs are the same then use as tie breaker the other other
   10580              :                  factor.  */
   10581          194 :               if (divmul_cost == modsub_cost)
   10582              :                 {
   10583            5 :                   divmul_cost = seq_cost (divmul_insns, !speed_p);
   10584            5 :                   modsub_cost = seq_cost (modsub_insns, !speed_p);
   10585              :                 }
   10586              : 
   10587          194 :               if (divmul_cost <= modsub_cost)
   10588              :                 {
   10589          121 :                   emit_insn (divmul_insns);
   10590          121 :                   return REDUCE_BIT_FIELD (divmul_ret);
   10591              :                 }
   10592           73 :               emit_insn (modsub_insns);
   10593           73 :               return REDUCE_BIT_FIELD (modsub_ret);
   10594              :             }
   10595              :         }
   10596              : 
   10597       894746 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10598              : 
   10599              :       /* Expand X*Y as X&-Y when Y must be zero or one.  */
   10600       894746 :       if (SCALAR_INT_MODE_P (mode))
   10601              :         {
   10602       761120 :           bool bit0_p = expr_has_boolean_range (treeop0, currently_expanding_gimple_stmt);
   10603       761120 :           bool bit1_p = expr_has_boolean_range (treeop1, currently_expanding_gimple_stmt);
   10604              : 
   10605              :           /* Expand X*Y as X&Y when both X and Y must be zero or one.  */
   10606       761120 :           if (bit0_p && bit1_p)
   10607            0 :             return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
   10608              : 
   10609       761120 :           if (bit0_p || bit1_p)
   10610              :             {
   10611         3175 :               bool speed = optimize_insn_for_speed_p ();
   10612         3175 :               int cost = add_cost (speed, mode) + neg_cost (speed, mode);
   10613         3175 :               struct algorithm algorithm;
   10614         3175 :               enum mult_variant variant;
   10615         3175 :               if (CONST_INT_P (op1)
   10616         3175 :                   ? !choose_mult_variant (mode, INTVAL (op1),
   10617              :                                           &algorithm, &variant, cost)
   10618          596 :                   : cost < mul_cost (speed, mode))
   10619              :                 {
   10620         1358 :                   temp = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
   10621              :                                               op1, target)
   10622          238 :                                 : expand_and (mode, op0,
   10623              :                                               negate_rtx (mode, op1),
   10624              :                                               target);
   10625         1358 :                   return REDUCE_BIT_FIELD (temp);
   10626              :                 }
   10627              :             }
   10628              :         }
   10629              : 
   10630       893388 :       return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
   10631              : 
   10632       168999 :     case TRUNC_MOD_EXPR:
   10633       168999 :     case FLOOR_MOD_EXPR:
   10634       168999 :     case CEIL_MOD_EXPR:
   10635       168999 :     case ROUND_MOD_EXPR:
   10636              : 
   10637       168999 :     case TRUNC_DIV_EXPR:
   10638       168999 :     case FLOOR_DIV_EXPR:
   10639       168999 :     case CEIL_DIV_EXPR:
   10640       168999 :     case ROUND_DIV_EXPR:
   10641       168999 :     case EXACT_DIV_EXPR:
   10642              :       /* If this is a fixed-point operation, then we cannot use the code
   10643              :          below because "expand_divmod" doesn't support sat/no-sat fixed-point
   10644              :          divisions.   */
   10645       168999 :       if (ALL_FIXED_POINT_MODE_P (mode))
   10646            0 :         goto binop;
   10647              : 
   10648       168999 :       if (modifier == EXPAND_STACK_PARM)
   10649          306 :         target = 0;
   10650              :       /* Possible optimization: compute the dividend with EXPAND_SUM
   10651              :          then if the divisor is constant can optimize the case
   10652              :          where some terms of the dividend have coeffs divisible by it.  */
   10653       168999 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10654       168999 :       return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
   10655       168999 :                                  target, unsignedp);
   10656              : 
   10657        31034 :     case RDIV_EXPR:
   10658        31034 :       goto binop;
   10659              : 
   10660         3507 :     case MULT_HIGHPART_EXPR:
   10661         3507 :       expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
   10662         3507 :       temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
   10663         3507 :       gcc_assert (temp);
   10664              :       return temp;
   10665              : 
   10666            0 :     case FIXED_CONVERT_EXPR:
   10667            0 :       op0 = expand_normal (treeop0);
   10668            0 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10669            0 :         target = gen_reg_rtx (mode);
   10670              : 
   10671            0 :       if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
   10672            0 :            && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10673            0 :           || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
   10674            0 :         expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
   10675              :       else
   10676            0 :         expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
   10677              :       return target;
   10678              : 
   10679        48287 :     case FIX_TRUNC_EXPR:
   10680        48287 :       op0 = expand_normal (treeop0);
   10681        48287 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10682         3414 :         target = gen_reg_rtx (mode);
   10683        48287 :       expand_fix (target, op0, unsignedp);
   10684        48287 :       return target;
   10685              : 
   10686       133350 :     case FLOAT_EXPR:
   10687       133350 :       op0 = expand_normal (treeop0);
   10688       133350 :       if (target == 0 || modifier == EXPAND_STACK_PARM)
   10689        62961 :         target = gen_reg_rtx (mode);
   10690              :       /* expand_float can't figure out what to do if FROM has VOIDmode.
   10691              :          So give it the correct mode.  With -O, cse will optimize this.  */
   10692       133350 :       if (GET_MODE (op0) == VOIDmode)
   10693          109 :         op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
   10694              :                                 op0);
   10695       266700 :       expand_float (target, op0,
   10696       133350 :                     TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   10697       133350 :       return target;
   10698              : 
   10699        59037 :     case NEGATE_EXPR:
   10700        59037 :       op0 = expand_expr (treeop0, subtarget,
   10701              :                          VOIDmode, EXPAND_NORMAL);
   10702        59037 :       if (modifier == EXPAND_STACK_PARM)
   10703          241 :         target = 0;
   10704        59037 :       temp = expand_unop (mode,
   10705              :                           optab_for_tree_code (NEGATE_EXPR, type,
   10706              :                                                optab_default),
   10707              :                           op0, target, 0);
   10708        59037 :       gcc_assert (temp);
   10709        59037 :       return REDUCE_BIT_FIELD (temp);
   10710              : 
   10711        28293 :     case ABS_EXPR:
   10712        28293 :     case ABSU_EXPR:
   10713        28293 :       op0 = expand_expr (treeop0, subtarget,
   10714              :                          VOIDmode, EXPAND_NORMAL);
   10715        28293 :       if (modifier == EXPAND_STACK_PARM)
   10716           63 :         target = 0;
   10717              : 
   10718              :       /* ABS_EXPR is not valid for complex arguments.  */
   10719        28293 :       gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
   10720              :                   && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
   10721              : 
   10722              :       /* Unsigned abs is simply the operand.  Testing here means we don't
   10723              :          risk generating incorrect code below.  */
   10724        28293 :       if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
   10725              :         return op0;
   10726              : 
   10727        28293 :       return expand_abs (mode, op0, target, unsignedp,
   10728        56586 :                          safe_from_p (target, treeop0, 1));
   10729              : 
   10730       136812 :     case MAX_EXPR:
   10731       136812 :     case MIN_EXPR:
   10732       136812 :       target = original_target;
   10733       136812 :       if (target == 0
   10734       136812 :           || modifier == EXPAND_STACK_PARM
   10735        77933 :           || (MEM_P (target) && MEM_VOLATILE_P (target))
   10736        77933 :           || GET_MODE (target) != mode
   10737       214745 :           || (REG_P (target)
   10738        71238 :               && REGNO (target) < FIRST_PSEUDO_REGISTER))
   10739        58879 :         target = gen_reg_rtx (mode);
   10740       136812 :       expand_operands (treeop0, treeop1,
   10741              :                        target, &op0, &op1, EXPAND_NORMAL);
   10742              : 
   10743              :       /* First try to do it with a special MIN or MAX instruction.
   10744              :          If that does not win, use a conditional jump to select the proper
   10745              :          value.  */
   10746       136812 :       this_optab = optab_for_tree_code (code, type, optab_default);
   10747       136812 :       temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
   10748              :                            OPTAB_WIDEN);
   10749       136812 :       if (temp != 0)
   10750              :         return temp;
   10751              : 
   10752          122 :       if (VECTOR_TYPE_P (type))
   10753            0 :         gcc_unreachable ();
   10754              : 
   10755              :       /* At this point, a MEM target is no longer useful; we will get better
   10756              :          code without it.  */
   10757              : 
   10758          122 :       if (! REG_P (target))
   10759            1 :         target = gen_reg_rtx (mode);
   10760              : 
   10761              :       /* If op1 was placed in target, swap op0 and op1.  */
   10762          122 :       if (target != op0 && target == op1)
   10763            0 :         std::swap (op0, op1);
   10764              : 
   10765              :       /* We generate better code and avoid problems with op1 mentioning
   10766              :          target by forcing op1 into a pseudo if it isn't a constant.  */
   10767          122 :       if (! CONSTANT_P (op1))
   10768           42 :         op1 = force_reg (mode, op1);
   10769              : 
   10770          122 :       {
   10771          122 :         enum rtx_code comparison_code;
   10772          122 :         rtx cmpop1 = op1;
   10773              : 
   10774          122 :         if (code == MAX_EXPR)
   10775           62 :           comparison_code = unsignedp ? GEU : GE;
   10776              :         else
   10777           60 :           comparison_code = unsignedp ? LEU : LE;
   10778              : 
   10779              :         /* Canonicalize to comparisons against 0.  */
   10780          122 :         if (op1 == const1_rtx)
   10781              :           {
   10782              :             /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
   10783              :                or (a != 0 ? a : 1) for unsigned.
   10784              :                For MIN we are safe converting (a <= 1 ? a : 1)
   10785              :                into (a <= 0 ? a : 1)  */
   10786            0 :             cmpop1 = const0_rtx;
   10787            0 :             if (code == MAX_EXPR)
   10788            0 :               comparison_code = unsignedp ? NE : GT;
   10789              :           }
   10790          122 :         if (op1 == constm1_rtx && !unsignedp)
   10791              :           {
   10792              :             /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
   10793              :                and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
   10794            0 :             cmpop1 = const0_rtx;
   10795            0 :             if (code == MIN_EXPR)
   10796            0 :               comparison_code = LT;
   10797              :           }
   10798              : 
   10799              :         /* Use a conditional move if possible.  */
   10800          122 :         if (can_conditionally_move_p (mode))
   10801              :           {
   10802           75 :             rtx insn;
   10803              : 
   10804           75 :             start_sequence ();
   10805              : 
   10806              :             /* Try to emit the conditional move.  */
   10807           75 :             insn = emit_conditional_move (target,
   10808              :                                           { comparison_code,
   10809              :                                             op0, cmpop1, mode },
   10810              :                                           op0, op1, mode,
   10811              :                                           unsignedp);
   10812              : 
   10813              :             /* If we could do the conditional move, emit the sequence,
   10814              :                and return.  */
   10815           75 :             if (insn)
   10816              :               {
   10817           41 :                 rtx_insn *seq = end_sequence ();
   10818           41 :                 emit_insn (seq);
   10819           41 :                 return target;
   10820              :               }
   10821              : 
   10822              :             /* Otherwise discard the sequence and fall back to code with
   10823              :                branches.  */
   10824           34 :             end_sequence ();
   10825              :           }
   10826              : 
   10827           81 :         if (target != op0)
   10828           52 :           emit_move_insn (target, op0);
   10829              : 
   10830           81 :         lab = gen_label_rtx ();
   10831           81 :         do_compare_rtx_and_jump (target, cmpop1, comparison_code,
   10832              :                                  unsignedp, mode, NULL_RTX, NULL, lab,
   10833              :                                  profile_probability::uninitialized ());
   10834              :       }
   10835           81 :       emit_move_insn (target, op1);
   10836           81 :       emit_label (lab);
   10837           81 :       return target;
   10838              : 
   10839        61192 :     case BIT_NOT_EXPR:
   10840        61192 :       op0 = expand_expr (treeop0, subtarget,
   10841              :                          VOIDmode, EXPAND_NORMAL);
   10842        61192 :       if (modifier == EXPAND_STACK_PARM)
   10843           90 :         target = 0;
   10844              :       /* In case we have to reduce the result to bitfield precision
   10845              :          for unsigned bitfield expand this as XOR with a proper constant
   10846              :          instead.  */
   10847        61192 :       if (reduce_bit_field && TYPE_UNSIGNED (type))
   10848              :         {
   10849        22149 :           int_mode = SCALAR_INT_TYPE_MODE (type);
   10850        22149 :           wide_int mask = wi::mask (TYPE_PRECISION (type),
   10851        44298 :                                     false, GET_MODE_PRECISION (int_mode));
   10852              : 
   10853        44298 :           temp = expand_binop (int_mode, xor_optab, op0,
   10854        44298 :                                immed_wide_int_const (mask, int_mode),
   10855              :                                target, 1, OPTAB_LIB_WIDEN);
   10856        22149 :         }
   10857              :       else
   10858        39043 :         temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
   10859        61192 :       gcc_assert (temp);
   10860              :       return temp;
   10861              : 
   10862              :       /* ??? Can optimize bitwise operations with one arg constant.
   10863              :          Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
   10864              :          and (a bitwise1 b) bitwise2 b (etc)
   10865              :          but that is probably not worth while.  */
   10866              : 
   10867       619578 :     case BIT_AND_EXPR:
   10868       619578 :     case BIT_IOR_EXPR:
   10869       619578 :     case BIT_XOR_EXPR:
   10870       619578 :       goto binop;
   10871              : 
   10872         8624 :     case LROTATE_EXPR:
   10873         8624 :     case RROTATE_EXPR:
   10874         8624 :       gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
   10875              :                   || type_has_mode_precision_p (type));
   10876              :       /* fall through */
   10877              : 
   10878       304705 :     case LSHIFT_EXPR:
   10879       304705 :     case RSHIFT_EXPR:
   10880       304705 :       {
   10881              :         /* If this is a fixed-point operation, then we cannot use the code
   10882              :            below because "expand_shift" doesn't support sat/no-sat fixed-point
   10883              :            shifts.  */
   10884       304705 :         if (ALL_FIXED_POINT_MODE_P (mode))
   10885            0 :           goto binop;
   10886              : 
   10887       304705 :         if (! safe_from_p (subtarget, treeop1, 1))
   10888         4903 :           subtarget = 0;
   10889       304705 :         if (modifier == EXPAND_STACK_PARM)
   10890         2586 :           target = 0;
   10891       304705 :         op0 = expand_expr (treeop0, subtarget,
   10892              :                            VOIDmode, EXPAND_NORMAL);
   10893              : 
   10894              :         /* Left shift optimization when shifting across word_size boundary.
   10895              : 
   10896              :            If mode == GET_MODE_WIDER_MODE (word_mode), then normally
   10897              :            there isn't native instruction to support this wide mode
   10898              :            left shift.  Given below scenario:
   10899              : 
   10900              :             Type A = (Type) B  << C
   10901              : 
   10902              :             |<                T          >|
   10903              :             | dest_high  |  dest_low |
   10904              : 
   10905              :                          | word_size |
   10906              : 
   10907              :            If the shift amount C caused we shift B to across the word
   10908              :            size boundary, i.e part of B shifted into high half of
   10909              :            destination register, and part of B remains in the low
   10910              :            half, then GCC will use the following left shift expand
   10911              :            logic:
   10912              : 
   10913              :            1. Initialize dest_low to B.
   10914              :            2. Initialize every bit of dest_high to the sign bit of B.
   10915              :            3. Logic left shift dest_low by C bit to finalize dest_low.
   10916              :               The value of dest_low before this shift is kept in a temp D.
   10917              :            4. Logic left shift dest_high by C.
   10918              :            5. Logic right shift D by (word_size - C).
   10919              :            6. Or the result of 4 and 5 to finalize dest_high.
   10920              : 
   10921              :            While, by checking gimple statements, if operand B is
   10922              :            coming from signed extension, then we can simplify above
   10923              :            expand logic into:
   10924              : 
   10925              :               1. dest_high = src_low >> (word_size - C).
   10926              :               2. dest_low = src_low << C.
   10927              : 
   10928              :            We can use one arithmetic right shift to finish all the
   10929              :            purpose of steps 2, 4, 5, 6, thus we reduce the steps
   10930              :            needed from 6 into 2.
   10931              : 
   10932              :            The case is similar for zero extension, except that we
   10933              :            initialize dest_high to zero rather than copies of the sign
   10934              :            bit from B.  Furthermore, we need to use a logical right shift
   10935              :            in this case.
   10936              : 
   10937              :            The choice of sign-extension versus zero-extension is
   10938              :            determined entirely by whether or not B is signed and is
   10939              :            independent of the current setting of unsignedp.  */
   10940              : 
   10941       304705 :         temp = NULL_RTX;
   10942       304705 :         if (code == LSHIFT_EXPR
   10943       304705 :             && target
   10944        33363 :             && REG_P (target)
   10945        30402 :             && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
   10946        30402 :             && mode == int_mode
   10947         1515 :             && TREE_CONSTANT (treeop1)
   10948       305553 :             && TREE_CODE (treeop0) == SSA_NAME)
   10949              :           {
   10950          848 :             gimple *def = SSA_NAME_DEF_STMT (treeop0);
   10951          848 :             if (is_gimple_assign (def)
   10952          848 :                 && gimple_assign_rhs_code (def) == NOP_EXPR)
   10953              :               {
   10954          337 :                 scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
   10955              :                   (TREE_TYPE (gimple_assign_rhs1 (def)));
   10956              : 
   10957          674 :                 if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
   10958          628 :                     && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
   10959          479 :                     && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
   10960           71 :                         >= GET_MODE_BITSIZE (word_mode)))
   10961              :                   {
   10962           67 :                     rtx_insn *seq, *seq_old;
   10963           67 :                     poly_uint64 high_off = subreg_highpart_offset (word_mode,
   10964              :                                                                    int_mode);
   10965           67 :                     bool extend_unsigned
   10966           67 :                       = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
   10967           67 :                     rtx low = lowpart_subreg (word_mode, op0, int_mode);
   10968           67 :                     rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
   10969           67 :                     rtx dest_high = simplify_gen_subreg (word_mode, target,
   10970              :                                                          int_mode, high_off);
   10971           67 :                     HOST_WIDE_INT ramount = (BITS_PER_WORD
   10972           67 :                                              - TREE_INT_CST_LOW (treeop1));
   10973           67 :                     tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
   10974              : 
   10975           67 :                     start_sequence ();
   10976              :                     /* dest_high = src_low >> (word_size - C).  */
   10977           67 :                     temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
   10978              :                                                   rshift, dest_high,
   10979              :                                                   extend_unsigned);
   10980           67 :                     if (temp != dest_high)
   10981            0 :                       emit_move_insn (dest_high, temp);
   10982              : 
   10983              :                     /* dest_low = src_low << C.  */
   10984           67 :                     temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
   10985              :                                                   treeop1, dest_low, unsignedp);
   10986           67 :                     if (temp != dest_low)
   10987            0 :                       emit_move_insn (dest_low, temp);
   10988              : 
   10989           67 :                     seq = end_sequence ();
   10990           67 :                     temp = target ;
   10991              : 
   10992           67 :                     if (have_insn_for (ASHIFT, int_mode))
   10993              :                       {
   10994           67 :                         bool speed_p = optimize_insn_for_speed_p ();
   10995           67 :                         start_sequence ();
   10996           67 :                         rtx ret_old = expand_variable_shift (code, int_mode,
   10997              :                                                              op0, treeop1,
   10998              :                                                              target,
   10999              :                                                              unsignedp);
   11000              : 
   11001           67 :                         seq_old = end_sequence ();
   11002          134 :                         if (seq_cost (seq, speed_p)
   11003           67 :                             >= seq_cost (seq_old, speed_p))
   11004              :                           {
   11005           67 :                             seq = seq_old;
   11006           67 :                             temp = ret_old;
   11007              :                           }
   11008              :                       }
   11009           67 :                       emit_insn (seq);
   11010              :                   }
   11011              :               }
   11012              :           }
   11013              : 
   11014           67 :         if (temp == NULL_RTX)
   11015       304638 :           temp = expand_variable_shift (code, mode, op0, treeop1, target,
   11016              :                                         unsignedp);
   11017       304705 :         if (code == LSHIFT_EXPR)
   11018        80711 :           temp = REDUCE_BIT_FIELD (temp);
   11019              :         return temp;
   11020              :       }
   11021              : 
   11022              :       /* Could determine the answer when only additive constants differ.  Also,
   11023              :          the addition of one can be handled by changing the condition.  */
   11024       639764 :     case LT_EXPR:
   11025       639764 :     case LE_EXPR:
   11026       639764 :     case GT_EXPR:
   11027       639764 :     case GE_EXPR:
   11028       639764 :     case EQ_EXPR:
   11029       639764 :     case NE_EXPR:
   11030       639764 :     case UNORDERED_EXPR:
   11031       639764 :     case ORDERED_EXPR:
   11032       639764 :     case UNLT_EXPR:
   11033       639764 :     case UNLE_EXPR:
   11034       639764 :     case UNGT_EXPR:
   11035       639764 :     case UNGE_EXPR:
   11036       639764 :     case UNEQ_EXPR:
   11037       639764 :     case LTGT_EXPR:
   11038       639764 :       {
   11039      1050960 :         temp = do_store_flag (ops,
   11040              :                               modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
   11041              :                               tmode != VOIDmode ? tmode : mode);
   11042       639764 :         if (temp)
   11043              :           return temp;
   11044              : 
   11045              :         /* Use a compare and a jump for BLKmode comparisons, or for function
   11046              :            type comparisons is have_canonicalize_funcptr_for_compare.  */
   11047              : 
   11048            0 :         if ((target == 0
   11049            0 :              || modifier == EXPAND_STACK_PARM
   11050            0 :              || ! safe_from_p (target, treeop0, 1)
   11051            0 :              || ! safe_from_p (target, treeop1, 1)
   11052              :              /* Make sure we don't have a hard reg (such as function's return
   11053              :                 value) live across basic blocks, if not optimizing.  */
   11054            0 :              || (!optimize && REG_P (target)
   11055            0 :                  && REGNO (target) < FIRST_PSEUDO_REGISTER)))
   11056            0 :           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
   11057              : 
   11058            0 :         emit_move_insn (target, const0_rtx);
   11059              : 
   11060            0 :         rtx_code_label *lab1 = gen_label_rtx ();
   11061            0 :         jumpifnot_1 (code, treeop0, treeop1, lab1,
   11062              :                      profile_probability::uninitialized ());
   11063              : 
   11064            0 :         if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
   11065            0 :           emit_move_insn (target, constm1_rtx);
   11066              :         else
   11067            0 :           emit_move_insn (target, const1_rtx);
   11068              : 
   11069            0 :         emit_label (lab1);
   11070            0 :         return target;
   11071              :       }
   11072        55658 :     case COMPLEX_EXPR:
   11073              :       /* Get the rtx code of the operands.  */
   11074        55658 :       op0 = expand_normal (treeop0);
   11075        55658 :       op1 = expand_normal (treeop1);
   11076              : 
   11077        55658 :       if (!target)
   11078         3108 :         target = gen_reg_rtx (TYPE_MODE (type));
   11079              :       else
   11080              :         /* If target overlaps with op1, then either we need to force
   11081              :            op1 into a pseudo (if target also overlaps with op0),
   11082              :            or write the complex parts in reverse order.  */
   11083        52550 :         switch (GET_CODE (target))
   11084              :           {
   11085        49791 :           case CONCAT:
   11086        49791 :             if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
   11087              :               {
   11088            0 :                 if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
   11089              :                   {
   11090            0 :                   complex_expr_force_op1:
   11091         1726 :                     temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
   11092          863 :                     emit_move_insn (temp, op1);
   11093          863 :                     op1 = temp;
   11094          863 :                     break;
   11095              :                   }
   11096            0 :               complex_expr_swap_order:
   11097              :                 /* Move the imaginary (op1) and real (op0) parts to their
   11098              :                    location.  */
   11099            1 :                 write_complex_part (target, op1, true, true);
   11100            1 :                 write_complex_part (target, op0, false, false);
   11101              : 
   11102            1 :                 return target;
   11103              :               }
   11104              :             break;
   11105         2759 :           case MEM:
   11106         5518 :             temp = adjust_address_nv (target,
   11107              :                                       GET_MODE_INNER (GET_MODE (target)), 0);
   11108         2759 :             if (reg_overlap_mentioned_p (temp, op1))
   11109              :               {
   11110          864 :                 scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
   11111         1728 :                 temp = adjust_address_nv (target, imode,
   11112              :                                           GET_MODE_SIZE (imode));
   11113          864 :                 if (reg_overlap_mentioned_p (temp, op0))
   11114          863 :                   goto complex_expr_force_op1;
   11115            1 :                 goto complex_expr_swap_order;
   11116              :               }
   11117              :             break;
   11118            0 :           default:
   11119            0 :             if (reg_overlap_mentioned_p (target, op1))
   11120              :               {
   11121            0 :                 if (reg_overlap_mentioned_p (target, op0))
   11122            0 :                   goto complex_expr_force_op1;
   11123            0 :                 goto complex_expr_swap_order;
   11124              :               }
   11125              :             break;
   11126              :           }
   11127              : 
   11128              :       /* Move the real (op0) and imaginary (op1) parts to their location.  */
   11129        55657 :       write_complex_part (target, op0, false, true);
   11130        55657 :       write_complex_part (target, op1, true, false);
   11131              : 
   11132        55657 :       return target;
   11133              : 
   11134            0 :     case WIDEN_SUM_EXPR:
   11135            0 :       {
   11136            0 :         tree oprnd0 = treeop0;
   11137            0 :         tree oprnd1 = treeop1;
   11138              : 
   11139            0 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11140            0 :         target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
   11141              :                                             target, unsignedp);
   11142            0 :         return target;
   11143              :       }
   11144              : 
   11145        17975 :     case VEC_UNPACK_HI_EXPR:
   11146        17975 :     case VEC_UNPACK_LO_EXPR:
   11147        17975 :     case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
   11148        17975 :     case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
   11149        17975 :       {
   11150        17975 :         op0 = expand_normal (treeop0);
   11151        17975 :         temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
   11152              :                                           target, unsignedp);
   11153        17975 :         gcc_assert (temp);
   11154              :         return temp;
   11155              :       }
   11156              : 
   11157         1760 :     case VEC_UNPACK_FLOAT_HI_EXPR:
   11158         1760 :     case VEC_UNPACK_FLOAT_LO_EXPR:
   11159         1760 :       {
   11160         1760 :         op0 = expand_normal (treeop0);
   11161              :         /* The signedness is determined from input operand.  */
   11162         1760 :         temp = expand_widen_pattern_expr
   11163         3520 :           (ops, op0, NULL_RTX, NULL_RTX,
   11164         1760 :            target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   11165              : 
   11166         1760 :         gcc_assert (temp);
   11167              :         return temp;
   11168              :       }
   11169              : 
   11170          995 :     case VEC_WIDEN_MULT_HI_EXPR:
   11171          995 :     case VEC_WIDEN_MULT_LO_EXPR:
   11172          995 :     case VEC_WIDEN_MULT_EVEN_EXPR:
   11173          995 :     case VEC_WIDEN_MULT_ODD_EXPR:
   11174          995 :     case VEC_WIDEN_LSHIFT_HI_EXPR:
   11175          995 :     case VEC_WIDEN_LSHIFT_LO_EXPR:
   11176          995 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11177          995 :       target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
   11178              :                                           target, unsignedp);
   11179          995 :       gcc_assert (target);
   11180              :       return target;
   11181              : 
   11182          370 :     case VEC_PACK_SAT_EXPR:
   11183          370 :     case VEC_PACK_FIX_TRUNC_EXPR:
   11184          370 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11185          370 :       subtarget = NULL_RTX;
   11186          370 :       goto binop;
   11187              : 
   11188        11486 :     case VEC_PACK_TRUNC_EXPR:
   11189        11486 :       if (VECTOR_BOOLEAN_TYPE_P (type)
   11190         2501 :           && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
   11191         2501 :           && mode == TYPE_MODE (TREE_TYPE (treeop0))
   11192        12194 :           && SCALAR_INT_MODE_P (mode))
   11193              :         {
   11194          708 :           class expand_operand eops[4];
   11195          708 :           machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
   11196          708 :           expand_operands (treeop0, treeop1,
   11197              :                            subtarget, &op0, &op1, EXPAND_NORMAL);
   11198          708 :           this_optab = vec_pack_sbool_trunc_optab;
   11199          708 :           enum insn_code icode = optab_handler (this_optab, imode);
   11200          708 :           create_output_operand (&eops[0], target, mode);
   11201          708 :           create_convert_operand_from (&eops[1], op0, imode, false);
   11202          708 :           create_convert_operand_from (&eops[2], op1, imode, false);
   11203          708 :           temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
   11204          708 :           create_input_operand (&eops[3], temp, imode);
   11205          708 :           expand_insn (icode, 4, eops);
   11206          708 :           return eops[0].value;
   11207              :         }
   11208        10778 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11209        10778 :       subtarget = NULL_RTX;
   11210        10778 :       goto binop;
   11211              : 
   11212           27 :     case VEC_PACK_FLOAT_EXPR:
   11213           27 :       mode = TYPE_MODE (TREE_TYPE (treeop0));
   11214           27 :       expand_operands (treeop0, treeop1,
   11215              :                        subtarget, &op0, &op1, EXPAND_NORMAL);
   11216           27 :       this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
   11217              :                                         optab_default);
   11218           81 :       target = expand_binop (mode, this_optab, op0, op1, target,
   11219           27 :                              TYPE_UNSIGNED (TREE_TYPE (treeop0)),
   11220              :                              OPTAB_LIB_WIDEN);
   11221           27 :       gcc_assert (target);
   11222              :       return target;
   11223              : 
   11224        76762 :     case VEC_PERM_EXPR:
   11225        76762 :       {
   11226        76762 :         expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL);
   11227        76762 :         vec_perm_builder sel;
   11228        76762 :         if (TREE_CODE (treeop2) == VECTOR_CST
   11229        76762 :             && tree_to_vec_perm_builder (&sel, treeop2))
   11230              :           {
   11231        76744 :             machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
   11232        76744 :             temp = expand_vec_perm_const (mode, op0, op1, sel,
   11233              :                                           sel_mode, target);
   11234              :           }
   11235              :         else
   11236              :           {
   11237           18 :             op2 = expand_normal (treeop2);
   11238           18 :             temp = expand_vec_perm_var (mode, op0, op1, op2, target);
   11239              :           }
   11240        76762 :         gcc_assert (temp);
   11241        76762 :         return temp;
   11242        76762 :       }
   11243              : 
   11244          441 :     case DOT_PROD_EXPR:
   11245          441 :       {
   11246          441 :         tree oprnd0 = treeop0;
   11247          441 :         tree oprnd1 = treeop1;
   11248          441 :         tree oprnd2 = treeop2;
   11249              : 
   11250          441 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11251          441 :         op2 = expand_normal (oprnd2);
   11252          441 :         target = expand_widen_pattern_expr (ops, op0, op1, op2,
   11253              :                                             target, unsignedp);
   11254          441 :         return target;
   11255              :       }
   11256              : 
   11257          119 :       case SAD_EXPR:
   11258          119 :       {
   11259          119 :         tree oprnd0 = treeop0;
   11260          119 :         tree oprnd1 = treeop1;
   11261          119 :         tree oprnd2 = treeop2;
   11262              : 
   11263          119 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11264          119 :         op2 = expand_normal (oprnd2);
   11265          119 :         target = expand_widen_pattern_expr (ops, op0, op1, op2,
   11266              :                                             target, unsignedp);
   11267          119 :         return target;
   11268              :       }
   11269              : 
   11270            0 :     case REALIGN_LOAD_EXPR:
   11271            0 :       {
   11272            0 :         tree oprnd0 = treeop0;
   11273            0 :         tree oprnd1 = treeop1;
   11274            0 :         tree oprnd2 = treeop2;
   11275              : 
   11276            0 :         this_optab = optab_for_tree_code (code, type, optab_default);
   11277            0 :         expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
   11278            0 :         op2 = expand_normal (oprnd2);
   11279            0 :         temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
   11280              :                                   target, unsignedp);
   11281            0 :         gcc_assert (temp);
   11282              :         return temp;
   11283              :       }
   11284              : 
   11285        17677 :     case COND_EXPR:
   11286        17677 :       {
   11287              :         /* A COND_EXPR with its type being VOID_TYPE represents a
   11288              :            conditional jump and is handled in
   11289              :            expand_gimple_cond_expr.  */
   11290        17677 :         gcc_assert (!VOID_TYPE_P (type));
   11291              : 
   11292              :         /* Note that COND_EXPRs whose type is a structure or union
   11293              :            are required to be constructed to contain assignments of
   11294              :            a temporary variable, so that we can evaluate them here
   11295              :            for side effect only.  If type is void, we must do likewise.  */
   11296              : 
   11297        17677 :         gcc_assert (!TREE_ADDRESSABLE (type)
   11298              :                     && !ignore
   11299              :                     && TREE_TYPE (treeop1) != void_type_node
   11300              :                     && TREE_TYPE (treeop2) != void_type_node);
   11301              : 
   11302        17677 :         temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
   11303        17677 :         if (temp)
   11304              :           return temp;
   11305              : 
   11306              :         /* If we are not to produce a result, we have no target.  Otherwise,
   11307              :            if a target was specified use it; it will not be used as an
   11308              :            intermediate target unless it is safe.  If no target, use a
   11309              :            temporary.  */
   11310              : 
   11311         3052 :         if (modifier != EXPAND_STACK_PARM
   11312         3052 :             && original_target
   11313         2257 :             && safe_from_p (original_target, treeop0, 1)
   11314            0 :             && GET_MODE (original_target) == mode
   11315         3052 :             && !MEM_P (original_target))
   11316              :           temp = original_target;
   11317              :         else
   11318         3052 :           temp = assign_temp (type, 0, 1);
   11319              : 
   11320         3052 :         do_pending_stack_adjust ();
   11321         3052 :         NO_DEFER_POP;
   11322         3052 :         rtx_code_label *lab0 = gen_label_rtx ();
   11323         3052 :         rtx_code_label *lab1 = gen_label_rtx ();
   11324         3052 :         jumpifnot (treeop0, lab0,
   11325              :                    profile_probability::uninitialized ());
   11326         3052 :         store_expr (treeop1, temp,
   11327              :                     modifier == EXPAND_STACK_PARM,
   11328              :                     false, false);
   11329              : 
   11330         3052 :         emit_jump_insn (targetm.gen_jump (lab1));
   11331         3052 :         emit_barrier ();
   11332         3052 :         emit_label (lab0);
   11333         3052 :         store_expr (treeop2, temp,
   11334              :                     modifier == EXPAND_STACK_PARM,
   11335              :                     false, false);
   11336              : 
   11337         3052 :         emit_label (lab1);
   11338         3052 :         OK_DEFER_POP;
   11339         3052 :         return temp;
   11340              :       }
   11341              : 
   11342            0 :     case VEC_DUPLICATE_EXPR:
   11343            0 :       op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
   11344            0 :       target = expand_vector_broadcast (mode, op0);
   11345            0 :       gcc_assert (target);
   11346              :       return target;
   11347              : 
   11348            0 :     case VEC_SERIES_EXPR:
   11349            0 :       expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
   11350            0 :       return expand_vec_series_expr (mode, op0, op1, target);
   11351              : 
   11352         1220 :     case BIT_INSERT_EXPR:
   11353         1220 :       {
   11354         1220 :         unsigned bitpos = tree_to_uhwi (treeop2);
   11355         1220 :         unsigned bitsize;
   11356         1220 :         if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
   11357          873 :           bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
   11358              :         else
   11359          347 :           bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
   11360         1220 :         op0 = expand_normal (treeop0);
   11361         1220 :         op1 = expand_normal (treeop1);
   11362         1220 :         rtx dst = gen_reg_rtx (mode);
   11363         1220 :         emit_move_insn (dst, op0);
   11364         1220 :         store_bit_field (dst, bitsize, bitpos, 0, 0,
   11365         1220 :                          TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
   11366         1220 :         return dst;
   11367              :       }
   11368              : 
   11369            0 :     default:
   11370            0 :       gcc_unreachable ();
   11371              :     }
   11372              : 
   11373              :   /* Here to do an ordinary binary operator.  */
   11374      1204024 :  binop:
   11375      1204024 :   expand_operands (treeop0, treeop1,
   11376              :                    subtarget, &op0, &op1, EXPAND_NORMAL);
   11377      5735496 :  binop2:
   11378      5735496 :   this_optab = optab_for_tree_code (code, type, optab_default);
   11379      5735496 :  binop3:
   11380      5735496 :   if (modifier == EXPAND_STACK_PARM)
   11381        27211 :     target = 0;
   11382      5735496 :   temp = expand_binop (mode, this_optab, op0, op1, target,
   11383              :                        unsignedp, OPTAB_LIB_WIDEN);
   11384      5735496 :   gcc_assert (temp);
   11385              :   /* Bitwise operations do not need bitfield reduction as we expect their
   11386              :      operands being properly truncated.  */
   11387      5735496 :   if (code == BIT_XOR_EXPR
   11388              :       || code == BIT_AND_EXPR
   11389      5735496 :       || code == BIT_IOR_EXPR)
   11390              :     return temp;
   11391      5115918 :   return REDUCE_BIT_FIELD (temp);
   11392              : }
   11393              : #undef REDUCE_BIT_FIELD
   11394              : 
   11395              : 
   11396              : /* Return TRUE if expression STMT is suitable for replacement.
   11397              :    Never consider memory loads as replaceable, because those don't ever lead
   11398              :    into constant expressions.  */
   11399              : 
   11400              : static bool
   11401            8 : stmt_is_replaceable_p (gimple *stmt)
   11402              : {
   11403            8 :   if (ssa_is_replaceable_p (stmt))
   11404              :     {
   11405              :       /* Don't move around loads.  */
   11406            7 :       if (!gimple_assign_single_p (stmt)
   11407            7 :           || is_gimple_val (gimple_assign_rhs1 (stmt)))
   11408            6 :         return true;
   11409              :     }
   11410              :   return false;
   11411              : }
   11412              : 
   11413              : /* A subroutine of expand_expr_real_1.  Expand gimple assignment G,
   11414              :    which is known to set an SSA_NAME result.  The other arguments are
   11415              :    as for expand_expr_real_1.  */
   11416              : 
   11417              : rtx
   11418     15257671 : expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
   11419              :                           enum expand_modifier modifier, rtx *alt_rtl,
   11420              :                           bool inner_reference_p)
   11421              : {
   11422     15257671 :   separate_ops ops;
   11423     15257671 :   rtx r;
   11424     15257671 :   location_t saved_loc = curr_insn_location ();
   11425     15257671 :   auto loc = gimple_location (g);
   11426     15257671 :   if (loc != UNKNOWN_LOCATION)
   11427     12200294 :     set_curr_insn_location (loc);
   11428     15257671 :   tree lhs = gimple_assign_lhs (g);
   11429     15257671 :   ops.code = gimple_assign_rhs_code (g);
   11430     15257671 :   ops.type = TREE_TYPE (lhs);
   11431     15257671 :   switch (get_gimple_rhs_class (ops.code))
   11432              :     {
   11433        96056 :     case GIMPLE_TERNARY_RHS:
   11434       192112 :       ops.op2 = gimple_assign_rhs3 (g);
   11435              :       /* Fallthru */
   11436      8181730 :     case GIMPLE_BINARY_RHS:
   11437      8181730 :       ops.op1 = gimple_assign_rhs2 (g);
   11438              : 
   11439              :       /* Try to expand conditional compare.  */
   11440      8181730 :       if (targetm.have_ccmp ())
   11441              :         {
   11442       164994 :           gcc_checking_assert (targetm.gen_ccmp_next != NULL);
   11443       164994 :           r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
   11444       164994 :           if (r)
   11445              :             break;
   11446              :         }
   11447              :       /* Fallthru */
   11448     11765539 :     case GIMPLE_UNARY_RHS:
   11449     11765539 :       ops.op0 = gimple_assign_rhs1 (g);
   11450     11765539 :       ops.location = loc;
   11451     11765539 :       r = expand_expr_real_2 (&ops, target, tmode, modifier);
   11452     11765539 :       break;
   11453      3492112 :     case GIMPLE_SINGLE_RHS:
   11454      3492112 :       {
   11455      3492112 :         r = expand_expr_real (gimple_assign_rhs1 (g), target,
   11456              :                               tmode, modifier, alt_rtl,
   11457              :                               inner_reference_p);
   11458      3492112 :         break;
   11459              :       }
   11460            0 :     default:
   11461            0 :       gcc_unreachable ();
   11462              :     }
   11463     15257671 :   set_curr_insn_location (saved_loc);
   11464     15257671 :   if (REG_P (r) && !REG_EXPR (r))
   11465      3983100 :     set_reg_attrs_for_decl_rtl (lhs, r);
   11466     15257671 :   return r;
   11467              : }
   11468              : 
   11469              : /* A subroutine of expand_expr_real_1.  Attempt to VIEW_CONVERT_EXPR
   11470              :    the complex expression OP0 to the vector mode MODE.  Store the
   11471              :    result at TARGET if possible (if TARGET is nonzero).  Returns
   11472              :    NULL_RTX on failure.  */
   11473              : static rtx
   11474         6665 : try_expand_complex_as_vector (machine_mode mode, rtx op0, rtx target)
   11475              : {
   11476         6665 :   if (COMPLEX_MODE_P (GET_MODE (op0))
   11477         1404 :       && VECTOR_MODE_P (mode)
   11478           58 :       && known_eq (GET_MODE_NUNITS (mode), 2)
   11479         6723 :       && GET_MODE_INNER (mode) == GET_MODE_INNER (GET_MODE (op0)))
   11480              :     {
   11481           29 :       enum insn_code icode = convert_optab_handler (vec_init_optab, mode,
   11482           29 :                                                     GET_MODE_INNER (mode));
   11483           29 :       if (icode != CODE_FOR_nothing)
   11484              :         {
   11485           29 :           if (!target || !REG_P (target))
   11486           16 :             target = gen_reg_rtx (mode);
   11487           29 :           rtx rpart = read_complex_part (op0, false);
   11488           29 :           rtx ipart = read_complex_part (op0, true);
   11489           29 :           if (!REG_P (rpart) && !CONSTANT_P (rpart))
   11490            0 :             rpart = force_reg (GET_MODE_INNER (mode), rpart);
   11491           29 :           if (!REG_P (ipart) && !CONSTANT_P (ipart))
   11492            0 :             ipart = force_reg (GET_MODE_INNER (mode), ipart);
   11493           29 :           rtvec vec = rtvec_alloc (2);
   11494           29 :           RTVEC_ELT (vec, 0) = rpart;
   11495           29 :           RTVEC_ELT (vec, 1) = ipart;
   11496           29 :           rtx par = gen_rtx_PARALLEL (mode, vec);
   11497           29 :           rtx_insn *insn = GEN_FCN (icode) (target, par);
   11498           29 :           if (insn)
   11499              :             {
   11500           29 :               emit_insn (insn);
   11501           29 :               return target;
   11502              :             }
   11503              :         }
   11504              :     }
   11505              :   return NULL_RTX;
   11506              : }
   11507              : 
   11508              : rtx
   11509    159478230 : expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
   11510              :                     enum expand_modifier modifier, rtx *alt_rtl,
   11511              :                     bool inner_reference_p)
   11512              : {
   11513    159478230 :   rtx op0, op1, temp, decl_rtl;
   11514    159478230 :   tree type;
   11515    159478230 :   int unsignedp;
   11516    159478230 :   machine_mode mode, dmode;
   11517    159478230 :   enum tree_code code = TREE_CODE (exp);
   11518    159478230 :   rtx subtarget, original_target;
   11519    159478230 :   int ignore;
   11520    159478230 :   bool reduce_bit_field;
   11521    159478230 :   location_t loc = EXPR_LOCATION (exp);
   11522    159478230 :   struct separate_ops ops;
   11523    159478230 :   tree treeop0, treeop1, treeop2;
   11524    159478230 :   tree ssa_name = NULL_TREE;
   11525    159478230 :   gimple *g;
   11526              : 
   11527              :   /* EXPAND_NORMAL is the only modifier that guarantees that a memory
   11528              :      reference describes a load.  Use store semantics otherwise.  */
   11529    159478230 :   const bool may_store_p = modifier != EXPAND_NORMAL;
   11530              : 
   11531              :   /* Some ABIs define padding bits in _BitInt uninitialized.  Normally, RTL
   11532              :      expansion sign/zero extends integral types with less than mode precision
   11533              :      when reading from bit-fields and after arithmetic operations (see
   11534              :      REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
   11535              :      on those extensions to have been already performed, but because of the
   11536              :      above for _BitInt they need to be sign/zero extended when reading from
   11537              :      locations that could be exposed to ABI boundaries (when loading from
   11538              :      objects in memory, or function arguments, return value).  Because we
   11539              :      internally extend after arithmetic operations, we can avoid doing that
   11540              :      when reading from SSA_NAMEs of vars.  */
   11541              : #define EXTEND_BITINT(expr) \
   11542              :   ((BITINT_TYPE_P (type)                                                \
   11543              :     && !bitint_extended                                                 \
   11544              :     && reduce_bit_field                                                 \
   11545              :     && mode != BLKmode                                                  \
   11546              :     && modifier != EXPAND_MEMORY                                        \
   11547              :     && modifier != EXPAND_WRITE                                         \
   11548              :     && modifier != EXPAND_INITIALIZER                                   \
   11549              :     && modifier != EXPAND_CONST_ADDRESS)                                \
   11550              :    ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
   11551              : 
   11552    159478230 :   type = TREE_TYPE (exp);
   11553    159478230 :   mode = TYPE_MODE (type);
   11554    159478230 :   unsignedp = TYPE_UNSIGNED (type);
   11555    159478230 :   if (BITINT_TYPE_P (type) && bitint_extended == -1)
   11556              :     {
   11557         9142 :       struct bitint_info info;
   11558         9142 :       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
   11559         9142 :       gcc_assert (ok);
   11560         9142 :       bitint_extended = info.extended;
   11561              :     }
   11562              : 
   11563    159478230 :   treeop0 = treeop1 = treeop2 = NULL_TREE;
   11564    159478230 :   if (!VL_EXP_CLASS_P (exp))
   11565    152679591 :     switch (TREE_CODE_LENGTH (code))
   11566              :       {
   11567      5598125 :         default:
   11568      5598125 :         case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
   11569     13715496 :         case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
   11570     28280127 :         case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
   11571              :         case 0: break;
   11572              :       }
   11573    159478230 :   ops.code = code;
   11574    159478230 :   ops.type = type;
   11575    159478230 :   ops.op0 = treeop0;
   11576    159478230 :   ops.op1 = treeop1;
   11577    159478230 :   ops.op2 = treeop2;
   11578    159478230 :   ops.location = loc;
   11579              : 
   11580    318956460 :   ignore = (target == const0_rtx
   11581    159478230 :             || ((CONVERT_EXPR_CODE_P (code)
   11582    154381443 :                  || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
   11583       963533 :                 && TREE_CODE (type) == VOID_TYPE));
   11584              : 
   11585              :   /* An operation in what may be a bit-field type needs the
   11586              :      result to be reduced to the precision of the bit-field type,
   11587              :      which is narrower than that of the type's mode.  */
   11588    318956223 :   reduce_bit_field = (!ignore
   11589    154990648 :                       && INTEGRAL_TYPE_P (type)
   11590     81740995 :                       && !type_has_mode_precision_p (type));
   11591              : 
   11592              :   /* If we are going to ignore this result, we need only do something
   11593              :      if there is a side-effect somewhere in the expression.  If there
   11594              :      is, short-circuit the most common cases here.  Note that we must
   11595              :      not call expand_expr with anything but const0_rtx in case this
   11596              :      is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  */
   11597              : 
   11598              :   if (ignore)
   11599              :     {
   11600      4487582 :       if (! TREE_SIDE_EFFECTS (exp))
   11601              :         return const0_rtx;
   11602              : 
   11603              :       /* Ensure we reference a volatile object even if value is ignored, but
   11604              :          don't do this if all we are doing is taking its address.  */
   11605      4487345 :       if (TREE_THIS_VOLATILE (exp)
   11606            0 :           && TREE_CODE (exp) != FUNCTION_DECL
   11607            0 :           && mode != VOIDmode && mode != BLKmode
   11608            0 :           && modifier != EXPAND_CONST_ADDRESS)
   11609              :         {
   11610            0 :           temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
   11611            0 :           if (MEM_P (temp))
   11612            0 :             copy_to_reg (temp);
   11613            0 :           return const0_rtx;
   11614              :         }
   11615              : 
   11616      4487345 :       if (TREE_CODE_CLASS (code) == tcc_unary
   11617              :           || code == BIT_FIELD_REF
   11618      4487345 :           || code == COMPONENT_REF
   11619      4487345 :           || code == INDIRECT_REF)
   11620            0 :         return expand_expr (treeop0, const0_rtx, VOIDmode,
   11621            0 :                             modifier);
   11622              : 
   11623      4487345 :       else if (TREE_CODE_CLASS (code) == tcc_binary
   11624      4487345 :                || TREE_CODE_CLASS (code) == tcc_comparison
   11625      4487345 :                || code == ARRAY_REF || code == ARRAY_RANGE_REF)
   11626              :         {
   11627            0 :           expand_expr (treeop0, const0_rtx, VOIDmode, modifier);
   11628            0 :           expand_expr (treeop1, const0_rtx, VOIDmode, modifier);
   11629            0 :           return const0_rtx;
   11630              :         }
   11631              : 
   11632              :       target = 0;
   11633              :     }
   11634              : 
   11635    159477993 :   if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
   11636        39607 :     target = 0;
   11637              : 
   11638              :   /* Use subtarget as the target for operand 0 of a binary operation.  */
   11639    159477993 :   subtarget = get_subtarget (target);
   11640    159477993 :   original_target = target;
   11641              : 
   11642    159477993 :   switch (code)
   11643              :     {
   11644        10822 :     case LABEL_DECL:
   11645        10822 :       {
   11646        10822 :         tree function = decl_function_context (exp);
   11647              : 
   11648        10822 :         temp = label_rtx (exp);
   11649        14766 :         temp = gen_rtx_LABEL_REF (Pmode, temp);
   11650              : 
   11651        10822 :         if (function != current_function_decl
   11652         1270 :             && function != 0)
   11653         1270 :           LABEL_REF_NONLOCAL_P (temp) = 1;
   11654              : 
   11655        10822 :         temp = gen_rtx_MEM (FUNCTION_MODE, temp);
   11656        10822 :         return temp;
   11657              :       }
   11658              : 
   11659     57595193 :     case SSA_NAME:
   11660              :       /* ??? ivopts calls expander, without any preparation from
   11661              :          out-of-ssa.  So fake instructions as if this was an access to the
   11662              :          base variable.  This unnecessarily allocates a pseudo, see how we can
   11663              :          reuse it, if partition base vars have it set already.  */
   11664     57595193 :       if (!currently_expanding_to_rtl)
   11665              :         {
   11666            0 :           tree var = SSA_NAME_VAR (exp);
   11667            0 :           if (var && DECL_RTL_SET_P (var))
   11668            0 :             return DECL_RTL (var);
   11669            0 :           return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
   11670            0 :                               LAST_VIRTUAL_REGISTER + 1);
   11671              :         }
   11672              : 
   11673     57595193 :       g = get_gimple_for_ssa_name (exp);
   11674              :       /* For EXPAND_INITIALIZER try harder to get something simpler.  */
   11675     57595193 :       if (g == NULL
   11676     57595193 :           && modifier == EXPAND_INITIALIZER
   11677           26 :           && !SSA_NAME_IS_DEFAULT_DEF (exp)
   11678           11 :           && (optimize || !SSA_NAME_VAR (exp)
   11679            1 :               || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
   11680           10 :           && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
   11681     57595201 :           && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
   11682            6 :         g = SSA_NAME_DEF_STMT (exp);
   11683     57595193 :       if (safe_is_a <gassign *> (g))
   11684      9204141 :         return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
   11685      9204141 :                                          modifier, alt_rtl, inner_reference_p);
   11686     48391052 :       else if (safe_is_a <gcall *> (g))
   11687              :         {
   11688              :           /* ???  internal call expansion doesn't follow the usual API
   11689              :              of returning the destination RTX and being passed a desired
   11690              :              target.  */
   11691        77244 :           if (modifier == EXPAND_WRITE)
   11692        38626 :             return DECL_RTL (SSA_NAME_VAR (exp));
   11693        38618 :           rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
   11694        38618 :           tree tmplhs = make_tree (TREE_TYPE (exp), dest);
   11695        38618 :           tree var_or_id = SSA_NAME_VAR (exp);
   11696              :           if (!var_or_id)
   11697        28510 :             var_or_id = SSA_NAME_IDENTIFIER (exp);
   11698        38618 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, tmplhs);
   11699        38618 :           expand_internal_call (as_a <gcall *> (g));
   11700        38618 :           SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, var_or_id);
   11701        38618 :           return dest;
   11702              :         }
   11703              : 
   11704     48313808 :       ssa_name = exp;
   11705     48313808 :       decl_rtl = get_rtx_for_ssa_name (ssa_name);
   11706     48313808 :       exp = SSA_NAME_VAR (ssa_name);
   11707              :       /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
   11708              :          SSA_NAME computed within the current function.  In such case the
   11709              :          value have been already extended before.  While if it is a function
   11710              :          parameter, result or some memory location, we need to be prepared
   11711              :          for some other compiler leaving the bits uninitialized.  */
   11712     18949586 :       if (!exp || VAR_P (exp))
   11713              :         reduce_bit_field = false;
   11714     48313808 :       goto expand_decl_rtl;
   11715              : 
   11716     19856577 :     case VAR_DECL:
   11717              :       /* Allow accel compiler to handle variables that require special
   11718              :          treatment, e.g. if they have been modified in some way earlier in
   11719              :          compilation by the adjust_private_decl OpenACC hook.  */
   11720     19856577 :       if (flag_openacc && targetm.goacc.expand_var_decl)
   11721              :         {
   11722            0 :           temp = targetm.goacc.expand_var_decl (exp);
   11723            0 :           if (temp)
   11724              :             return temp;
   11725              :         }
   11726              :       /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
   11727              :          have scalar integer modes to a reg via store_constructor.  */
   11728     19856577 :       if (TREE_READONLY (exp)
   11729      3379063 :           && !TREE_SIDE_EFFECTS (exp)
   11730      3356655 :           && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
   11731        18532 :           && immediate_const_ctor_p (DECL_INITIAL (exp))
   11732          163 :           && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
   11733          127 :           && crtl->emit.regno_pointer_align_length
   11734     19856704 :           && !target)
   11735              :         {
   11736           88 :           target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
   11737           88 :           store_constructor (DECL_INITIAL (exp), target, 0,
   11738           88 :                              int_expr_size (DECL_INITIAL (exp)), false);
   11739           88 :           return target;
   11740              :         }
   11741              :       /* ... fall through ...  */
   11742              : 
   11743     20400877 :     case PARM_DECL:
   11744              :       /* If a static var's type was incomplete when the decl was written,
   11745              :          but the type is complete now, lay out the decl now.  */
   11746     20400877 :       if (DECL_SIZE (exp) == 0
   11747        45206 :           && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
   11748     20445971 :           && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
   11749        45094 :         layout_decl (exp, 0);
   11750              : 
   11751              :       /* fall through */
   11752              : 
   11753     21866176 :     case FUNCTION_DECL:
   11754     21866176 :     case RESULT_DECL:
   11755     21866176 :       decl_rtl = DECL_RTL (exp);
   11756     70179984 :     expand_decl_rtl:
   11757     70179984 :       gcc_assert (decl_rtl);
   11758              : 
   11759              :       /* DECL_MODE might change when TYPE_MODE depends on attribute target
   11760              :          settings for VECTOR_TYPE_P that might switch for the function.  */
   11761     70179984 :       if (currently_expanding_to_rtl
   11762     66496100 :           && code == VAR_DECL && MEM_P (decl_rtl)
   11763     85008630 :           && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
   11764           61 :         decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
   11765              :       else
   11766     70179923 :         decl_rtl = copy_rtx (decl_rtl);
   11767              : 
   11768     70179984 :       if (exp && MEM_P (decl_rtl))
   11769     22792079 :         MEM_NOTRAP_P (decl_rtl)
   11770     45584158 :           = !(may_store_p
   11771     22792079 :               ? lhs_could_trap_p (exp) : tree_could_trap_p (exp));
   11772              : 
   11773              :       /* Record writes to register variables.  */
   11774     70179984 :       if (modifier == EXPAND_WRITE
   11775     22044100 :           && REG_P (decl_rtl)
   11776     86307225 :           && HARD_REGISTER_P (decl_rtl))
   11777         2026 :         add_to_hard_reg_set (&crtl->asm_clobbers,
   11778         2026 :                              GET_MODE (decl_rtl), REGNO (decl_rtl));
   11779              : 
   11780              :       /* Ensure variable marked as used even if it doesn't go through
   11781              :          a parser.  If it hasn't be used yet, write out an external
   11782              :          definition.  */
   11783     70179984 :       if (exp)
   11784     40815762 :         TREE_USED (exp) = 1;
   11785              : 
   11786              :       /* Show we haven't gotten RTL for this yet.  */
   11787    110995746 :       temp = 0;
   11788              : 
   11789              :       /* Variables inherited from containing functions should have
   11790              :          been lowered by this point.  */
   11791     40815762 :       if (exp)
   11792              :         {
   11793     40815762 :           tree context = decl_function_context (exp);
   11794     40815762 :           gcc_assert (SCOPE_FILE_SCOPE_P (context)
   11795              :                       || context == current_function_decl
   11796              :                       || TREE_STATIC (exp)
   11797              :                       || DECL_EXTERNAL (exp)
   11798              :                       /* ??? C++ creates functions that are not
   11799              :                          TREE_STATIC.  */
   11800              :                       || TREE_CODE (exp) == FUNCTION_DECL);
   11801              :         }
   11802              : 
   11803              :       /* This is the case of an array whose size is to be determined
   11804              :          from its initializer, while the initializer is still being parsed.
   11805              :          ??? We aren't parsing while expanding anymore.  */
   11806              : 
   11807     70179984 :       if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
   11808       394661 :         temp = validize_mem (decl_rtl);
   11809              : 
   11810              :       /* If DECL_RTL is memory, we are in the normal case and the
   11811              :          address is not valid, get the address into a register.  */
   11812              : 
   11813     69785323 :       else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
   11814              :         {
   11815     18899433 :           if (alt_rtl)
   11816      2026740 :             *alt_rtl = decl_rtl;
   11817     18899433 :           decl_rtl = use_anchored_address (decl_rtl);
   11818     18899433 :           if (modifier != EXPAND_CONST_ADDRESS
   11819     18899433 :               && modifier != EXPAND_SUM
   11820     31282410 :               && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
   11821        17436 :                                                : GET_MODE (decl_rtl),
   11822              :                                                XEXP (decl_rtl, 0),
   11823     12382977 :                                                MEM_ADDR_SPACE (decl_rtl)))
   11824       137196 :             temp = replace_equiv_address (decl_rtl,
   11825              :                                           copy_rtx (XEXP (decl_rtl, 0)));
   11826              :         }
   11827              : 
   11828              :       /* If we got something, return it.  But first, set the alignment
   11829              :          if the address is a register.  */
   11830     19294094 :       if (temp != 0)
   11831              :         {
   11832       531857 :           if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
   11833       499942 :             mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
   11834              :         }
   11835     69648127 :       else if (MEM_P (decl_rtl))
   11836              :         temp = decl_rtl;
   11837              : 
   11838     47870411 :       if (temp != 0)
   11839              :         {
   11840     22809525 :           if (MEM_P (temp)
   11841              :               && modifier != EXPAND_WRITE
   11842     22809525 :               && modifier != EXPAND_MEMORY
   11843              :               && modifier != EXPAND_INITIALIZER
   11844     16831285 :               && modifier != EXPAND_CONST_ADDRESS
   11845      6966169 :               && modifier != EXPAND_SUM
   11846      6966169 :               && !inner_reference_p
   11847      4566751 :               && mode != BLKmode
   11848     27008352 :               && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
   11849        20131 :             temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
   11850        20131 :                                               MEM_ALIGN (temp), NULL_RTX, NULL);
   11851              : 
   11852     22809525 :           return EXTEND_BITINT (temp);
   11853              :         }
   11854              : 
   11855     47370459 :       if (exp)
   11856     18023683 :         dmode = DECL_MODE (exp);
   11857              :       else
   11858     29346776 :         dmode = TYPE_MODE (TREE_TYPE (ssa_name));
   11859              : 
   11860              :       /* If the mode of DECL_RTL does not match that of the decl,
   11861              :          there are two cases: we are dealing with a BLKmode value
   11862              :          that is returned in a register, or we are dealing with
   11863              :          a promoted value.  In the latter case, return a SUBREG
   11864              :          of the wanted mode, but mark it so that we know that it
   11865              :          was already extended.  */
   11866     47370459 :       if (REG_P (decl_rtl)
   11867     46834113 :           && dmode != BLKmode
   11868     46834113 :           && GET_MODE (decl_rtl) != dmode)
   11869              :         {
   11870           84 :           machine_mode pmode;
   11871              : 
   11872              :           /* Get the signedness to be used for this variable.  Ensure we get
   11873              :              the same mode we got when the variable was declared.  */
   11874           84 :           if (code != SSA_NAME)
   11875            0 :             pmode = promote_decl_mode (exp, &unsignedp);
   11876           84 :           else if ((g = SSA_NAME_DEF_STMT (ssa_name))
   11877           84 :                    && gimple_code (g) == GIMPLE_CALL
   11878           86 :                    && !gimple_call_internal_p (g))
   11879            2 :             pmode = promote_function_mode (type, mode, &unsignedp,
   11880            2 :                                            gimple_call_fntype (g),
   11881              :                                            2);
   11882              :           else
   11883           82 :             pmode = promote_ssa_mode (ssa_name, &unsignedp);
   11884           84 :           gcc_assert (GET_MODE (decl_rtl) == pmode);
   11885              : 
   11886              :           /* Some ABIs require scalar floating point modes to be passed
   11887              :              in a wider scalar integer mode.  We need to explicitly
   11888              :              truncate to an integer mode of the correct precision before
   11889              :              using a SUBREG to reinterpret as a floating point value.  */
   11890           84 :           if (SCALAR_FLOAT_MODE_P (mode)
   11891            0 :               && SCALAR_INT_MODE_P (pmode)
   11892           84 :               && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
   11893            0 :             return convert_wider_int_to_float (mode, pmode, decl_rtl);
   11894              : 
   11895           84 :           temp = gen_lowpart_SUBREG (mode, decl_rtl);
   11896           84 :           SUBREG_PROMOTED_VAR_P (temp) = 1;
   11897           84 :           SUBREG_PROMOTED_SET (temp, unsignedp);
   11898           84 :           return EXTEND_BITINT (temp);
   11899              :         }
   11900              : 
   11901     47370375 :       return EXTEND_BITINT (decl_rtl);
   11902              : 
   11903     43101505 :     case INTEGER_CST:
   11904     43101505 :       {
   11905     43101505 :         if (BITINT_TYPE_P (type))
   11906              :           {
   11907        11971 :             unsigned int prec = TYPE_PRECISION (type);
   11908        11971 :             struct bitint_info info;
   11909        11971 :             bool ok = targetm.c.bitint_type_info (prec, &info);
   11910        11971 :             gcc_assert (ok);
   11911        11971 :             scalar_int_mode limb_mode
   11912        11971 :               = as_a <scalar_int_mode> (info.limb_mode);
   11913        11971 :             unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
   11914        19624 :             if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
   11915              :               {
   11916              :                 /* Emit large/huge _BitInt INTEGER_CSTs into memory.  */
   11917         5159 :                 exp = tree_output_constant_def (exp);
   11918         5159 :                 return expand_expr (exp, target, VOIDmode, modifier);
   11919              :               }
   11920              :           }
   11921              : 
   11922              :         /* Given that TYPE_PRECISION (type) is not always equal to
   11923              :            GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
   11924              :            the former to the latter according to the signedness of the
   11925              :            type.  */
   11926     43096346 :         scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
   11927     43096346 :         temp = immed_wide_int_const
   11928     43096346 :           (wi::to_wide (exp, GET_MODE_PRECISION (int_mode)), int_mode);
   11929     43096346 :         return temp;
   11930              :       }
   11931              : 
   11932       574157 :     case VECTOR_CST:
   11933       574157 :       {
   11934       574157 :         tree tmp = NULL_TREE;
   11935       574157 :         if (VECTOR_MODE_P (mode))
   11936       571288 :           return const_vector_from_tree (exp);
   11937         2869 :         scalar_int_mode int_mode;
   11938         2869 :         if (is_int_mode (mode, &int_mode))
   11939              :           {
   11940          926 :             tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
   11941          926 :             if (type_for_mode)
   11942          926 :               tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
   11943              :                                     type_for_mode, exp);
   11944              :           }
   11945          926 :         if (!tmp)
   11946              :           {
   11947         1943 :             vec<constructor_elt, va_gc> *v;
   11948              :             /* Constructors need to be fixed-length.  FIXME.  */
   11949         1943 :             unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
   11950         1943 :             vec_alloc (v, nunits);
   11951        31617 :             for (unsigned int i = 0; i < nunits; ++i)
   11952        27731 :               CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
   11953         1943 :             tmp = build_constructor (type, v);
   11954              :           }
   11955         2869 :         return expand_expr (tmp, ignore ? const0_rtx : target,
   11956         2869 :                             tmode, modifier);
   11957              :       }
   11958              : 
   11959          136 :     case CONST_DECL:
   11960          136 :       if (modifier == EXPAND_WRITE)
   11961              :         {
   11962              :           /* Writing into CONST_DECL is always invalid, but handle it
   11963              :              gracefully.  */
   11964            2 :           addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
   11965            2 :           scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
   11966            2 :           op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
   11967              :                                          EXPAND_NORMAL, as);
   11968            2 :           op0 = memory_address_addr_space (mode, op0, as);
   11969            2 :           temp = gen_rtx_MEM (mode, op0);
   11970            2 :           set_mem_addr_space (temp, as);
   11971            2 :           return temp;
   11972              :         }
   11973          134 :       return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
   11974              : 
   11975       866457 :     case REAL_CST:
   11976              :       /* If optimized, generate immediate CONST_DOUBLE
   11977              :          which will be turned into memory by reload if necessary.
   11978              : 
   11979              :          We used to force a register so that loop.c could see it.  But
   11980              :          this does not allow gen_* patterns to perform optimizations with
   11981              :          the constants.  It also produces two insns in cases like "x = 1.0;".
   11982              :          On most machines, floating-point constants are not permitted in
   11983              :          many insns, so we'd end up copying it to a register in any case.
   11984              : 
   11985              :          Now, we do the copying in expand_binop, if appropriate.  */
   11986       866457 :       return const_double_from_real_value (TREE_REAL_CST (exp),
   11987      1732914 :                                            TYPE_MODE (TREE_TYPE (exp)));
   11988              : 
   11989            0 :     case FIXED_CST:
   11990            0 :       return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
   11991              :                                            TYPE_MODE (TREE_TYPE (exp)));
   11992              : 
   11993        18408 :     case COMPLEX_CST:
   11994              :       /* Handle evaluating a complex constant in a CONCAT target.  */
   11995        18408 :       if (original_target && GET_CODE (original_target) == CONCAT)
   11996              :         {
   11997          231 :           rtx rtarg, itarg;
   11998              : 
   11999          231 :           mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
   12000          231 :           rtarg = XEXP (original_target, 0);
   12001          231 :           itarg = XEXP (original_target, 1);
   12002              : 
   12003              :           /* Move the real and imaginary parts separately.  */
   12004          231 :           op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, EXPAND_NORMAL);
   12005          231 :           op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, EXPAND_NORMAL);
   12006              : 
   12007          231 :           if (op0 != rtarg)
   12008          231 :             emit_move_insn (rtarg, op0);
   12009          231 :           if (op1 != itarg)
   12010          231 :             emit_move_insn (itarg, op1);
   12011              : 
   12012              :           return original_target;
   12013              :         }
   12014              : 
   12015              :       /* fall through */
   12016              : 
   12017       202910 :     case STRING_CST:
   12018       202910 :       temp = expand_expr_constant (exp, 1, modifier);
   12019              : 
   12020              :       /* temp contains a constant address.
   12021              :          On RISC machines where a constant address isn't valid,
   12022              :          make some insns to get that address into a register.  */
   12023       202910 :       if (modifier != EXPAND_CONST_ADDRESS
   12024              :           && modifier != EXPAND_INITIALIZER
   12025       202910 :           && modifier != EXPAND_SUM
   12026       221464 :           && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
   12027        18554 :                                             MEM_ADDR_SPACE (temp)))
   12028           12 :         return replace_equiv_address (temp,
   12029           12 :                                       copy_rtx (XEXP (temp, 0)));
   12030              :       return temp;
   12031              : 
   12032            0 :     case POLY_INT_CST:
   12033            0 :       return immed_wide_int_const (poly_int_cst_value (exp), mode);
   12034              : 
   12035         1658 :     case SAVE_EXPR:
   12036         1658 :       {
   12037         1658 :         tree val = treeop0;
   12038         1658 :         rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
   12039              :                                       inner_reference_p);
   12040              : 
   12041         1658 :         if (!SAVE_EXPR_RESOLVED_P (exp))
   12042              :           {
   12043              :             /* We can indeed still hit this case, typically via builtin
   12044              :                expanders calling save_expr immediately before expanding
   12045              :                something.  Assume this means that we only have to deal
   12046              :                with non-BLKmode values.  */
   12047         1611 :             gcc_assert (GET_MODE (ret) != BLKmode);
   12048              : 
   12049         1611 :             val = build_decl (curr_insn_location (),
   12050         1611 :                               VAR_DECL, NULL, TREE_TYPE (exp));
   12051         1611 :             DECL_ARTIFICIAL (val) = 1;
   12052         1611 :             DECL_IGNORED_P (val) = 1;
   12053         1611 :             treeop0 = val;
   12054         1611 :             TREE_OPERAND (exp, 0) = treeop0;
   12055         1611 :             SAVE_EXPR_RESOLVED_P (exp) = 1;
   12056              : 
   12057         1611 :             if (!CONSTANT_P (ret))
   12058         1611 :               ret = copy_to_reg (ret);
   12059         1611 :             SET_DECL_RTL (val, ret);
   12060              :           }
   12061              : 
   12062              :         return ret;
   12063              :       }
   12064              : 
   12065              : 
   12066       181781 :     case CONSTRUCTOR:
   12067              :       /* If we don't need the result, just ensure we evaluate any
   12068              :          subexpressions.  */
   12069       181781 :       if (ignore)
   12070              :         {
   12071              :           unsigned HOST_WIDE_INT idx;
   12072              :           tree value;
   12073              : 
   12074            0 :           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
   12075            0 :             expand_expr (value, const0_rtx, VOIDmode, EXPAND_NORMAL);
   12076              : 
   12077            0 :           return const0_rtx;
   12078              :         }
   12079              : 
   12080       181781 :       return expand_constructor (exp, target, modifier, false);
   12081              : 
   12082       856965 :     case TARGET_MEM_REF:
   12083       856965 :       {
   12084       856965 :         addr_space_t as
   12085       856965 :           = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
   12086       856965 :         unsigned int align;
   12087              : 
   12088       856965 :         op0 = addr_for_mem_ref (exp, as, true);
   12089       856965 :         op0 = memory_address_addr_space (mode, op0, as);
   12090       856965 :         temp = gen_rtx_MEM (mode, op0);
   12091       856965 :         set_mem_attributes (temp, exp, 0, may_store_p);
   12092       856965 :         set_mem_addr_space (temp, as);
   12093       856965 :         align = get_object_alignment (exp);
   12094       856965 :         if (modifier != EXPAND_WRITE
   12095       856965 :             && modifier != EXPAND_MEMORY
   12096       591885 :             && mode != BLKmode
   12097      1442909 :             && align < GET_MODE_ALIGNMENT (mode))
   12098        53545 :           temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
   12099              :                                             align, NULL_RTX, NULL);
   12100       856965 :         return EXTEND_BITINT (temp);
   12101              :       }
   12102              : 
   12103      6811764 :     case MEM_REF:
   12104      6811764 :       {
   12105      6811764 :         const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
   12106      6811764 :         addr_space_t as
   12107      6811764 :           = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
   12108      6811764 :         machine_mode address_mode;
   12109      6811764 :         tree base = TREE_OPERAND (exp, 0);
   12110      6811764 :         gimple *def_stmt;
   12111      6811764 :         unsigned align;
   12112              :         /* Handle expansion of non-aliased memory with non-BLKmode.  That
   12113              :            might end up in a register.  */
   12114      6811764 :         if (mem_ref_refers_to_non_mem_p (exp))
   12115              :           {
   12116        80946 :             poly_int64 offset = mem_ref_offset (exp).force_shwi ();
   12117        80946 :             base = TREE_OPERAND (base, 0);
   12118        80946 :             poly_uint64 type_size;
   12119        80946 :             if (known_eq (offset, 0)
   12120        46559 :                 && !reverse
   12121        46559 :                 && poly_int_tree_p (TYPE_SIZE (type), &type_size)
   12122       174064 :                 && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
   12123        19453 :               return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
   12124        19453 :                                   target, tmode, modifier);
   12125        61493 :             unsigned align;
   12126        61493 :             if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
   12127              :               {
   12128          218 :                 temp = assign_stack_temp (DECL_MODE (base),
   12129          436 :                                           GET_MODE_SIZE (DECL_MODE (base)));
   12130          218 :                 store_expr (base, temp, 0, false, false);
   12131          218 :                 temp = adjust_address (temp, TYPE_MODE (type), offset);
   12132          218 :                 if (TYPE_MODE (type) == BLKmode)
   12133          197 :                   set_mem_size (temp, int_size_in_bytes (type));
   12134              :                 /* When the original ref was misaligned so will be the
   12135              :                    access to the stack temporary.  Not all targets handle
   12136              :                    this correctly, some will ICE in sanity checking.
   12137              :                    Handle this by doing bitfield extraction when necessary.  */
   12138           42 :                 else if ((align = get_object_alignment (exp))
   12139           21 :                          < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
   12140            3 :                   temp
   12141            3 :                     = expand_misaligned_mem_ref (temp, TYPE_MODE (type),
   12142              :                                                  unsignedp, align,
   12143              :                                                  modifier == EXPAND_STACK_PARM
   12144              :                                                  ? NULL_RTX : target, NULL);
   12145              :                 return temp;
   12146              :               }
   12147              :             /* When the access is fully outside of the underlying object
   12148              :                expand the offset as zero.  This avoids out-of-bound
   12149              :                BIT_FIELD_REFs and generates smaller code for these cases
   12150              :                with UB.  */
   12151        61275 :             type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
   12152       122550 :             if (!ranges_maybe_overlap_p (offset, type_size, 0,
   12153       122550 :                                          GET_MODE_SIZE (DECL_MODE (base))))
   12154           37 :               offset = 0;
   12155        61275 :             exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
   12156        61275 :                           bitsize_int (offset * BITS_PER_UNIT));
   12157        61275 :             REF_REVERSE_STORAGE_ORDER (exp) = reverse;
   12158        61275 :             return expand_expr (exp, target, tmode, modifier);
   12159              :           }
   12160      6730818 :         address_mode = targetm.addr_space.address_mode (as);
   12161      6730818 :         if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
   12162              :           {
   12163           44 :             tree mask = gimple_assign_rhs2 (def_stmt);
   12164           44 :             base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
   12165              :                            gimple_assign_rhs1 (def_stmt), mask);
   12166           44 :             TREE_OPERAND (exp, 0) = base;
   12167              :           }
   12168      6730818 :         align = get_object_alignment (exp);
   12169      6730818 :         op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
   12170      6730818 :         op0 = memory_address_addr_space (mode, op0, as);
   12171      6730818 :         if (!integer_zerop (TREE_OPERAND (exp, 1)))
   12172              :           {
   12173      2051000 :             rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
   12174      2051000 :             op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
   12175      2051000 :             op0 = memory_address_addr_space (mode, op0, as);
   12176              :           }
   12177      6730818 :         temp = gen_rtx_MEM (mode, op0);
   12178      6730818 :         set_mem_attributes (temp, exp, 0, may_store_p);
   12179      6730818 :         set_mem_addr_space (temp, as);
   12180      6730818 :         if (TREE_THIS_VOLATILE (exp))
   12181        12404 :           MEM_VOLATILE_P (temp) = 1;
   12182      6730818 :         if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
   12183              :           return temp;
   12184      3988586 :         if (!inner_reference_p
   12185      2063845 :             && mode != BLKmode
   12186      5990723 :             && align < GET_MODE_ALIGNMENT (mode))
   12187       146650 :           temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
   12188              :                                             modifier == EXPAND_STACK_PARM
   12189              :                                             ? NULL_RTX : target, alt_rtl);
   12190      3988586 :         if (reverse)
   12191           16 :           temp = flip_storage_order (mode, temp);
   12192      3988586 :         return EXTEND_BITINT (temp);
   12193              :       }
   12194              : 
   12195       629950 :     case ARRAY_REF:
   12196              : 
   12197       629950 :       {
   12198       629950 :         tree array = treeop0;
   12199       629950 :         tree index = treeop1;
   12200       629950 :         tree init;
   12201              : 
   12202              :         /* Fold an expression like: "foo"[2].
   12203              :            This is not done in fold so it won't happen inside &.
   12204              :            Don't fold if this is for wide characters since it's too
   12205              :            difficult to do correctly and this is a very rare case.  */
   12206              : 
   12207       629950 :         if (modifier != EXPAND_CONST_ADDRESS
   12208       629950 :             && modifier != EXPAND_INITIALIZER
   12209       629950 :             && modifier != EXPAND_MEMORY)
   12210              :           {
   12211       629845 :             tree t = fold_read_from_constant_string (exp);
   12212              : 
   12213       629845 :             if (t)
   12214            0 :               return expand_expr (t, target, tmode, modifier);
   12215              :           }
   12216              : 
   12217              :         /* If this is a constant index into a constant array,
   12218              :            just get the value from the array.  Handle both the cases when
   12219              :            we have an explicit constructor and when our operand is a variable
   12220              :            that was declared const.  */
   12221              : 
   12222       629950 :         if (modifier != EXPAND_CONST_ADDRESS
   12223              :             && modifier != EXPAND_INITIALIZER
   12224              :             && modifier != EXPAND_MEMORY
   12225       629845 :             && TREE_CODE (array) == CONSTRUCTOR
   12226            0 :             && ! TREE_SIDE_EFFECTS (array)
   12227       629950 :             && TREE_CODE (index) == INTEGER_CST)
   12228              :           {
   12229              :             unsigned HOST_WIDE_INT ix;
   12230              :             tree field, value;
   12231              : 
   12232            0 :             FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
   12233              :                                       field, value)
   12234            0 :               if (tree_int_cst_equal (field, index))
   12235              :                 {
   12236            0 :                   if (!TREE_SIDE_EFFECTS (value)
   12237            0 :                       && TREE_CODE (value) != RAW_DATA_CST)
   12238            0 :                     return expand_expr (fold (value), target, tmode, modifier);
   12239              :                   break;
   12240              :                 }
   12241              :           }
   12242              : 
   12243       629950 :         else if (optimize >= 1
   12244              :                  && modifier != EXPAND_CONST_ADDRESS
   12245       359577 :                  && modifier != EXPAND_INITIALIZER
   12246       359577 :                  && modifier != EXPAND_MEMORY
   12247       359476 :                  && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
   12248         9124 :                  && TREE_CODE (index) == INTEGER_CST
   12249         2120 :                  && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
   12250       630099 :                  && (init = ctor_for_folding (array)) != error_mark_node)
   12251              :           {
   12252          108 :             if (init == NULL_TREE)
   12253              :               {
   12254            5 :                 tree value = build_zero_cst (type);
   12255            5 :                 if (TREE_CODE (value) == CONSTRUCTOR)
   12256              :                   {
   12257              :                     /* If VALUE is a CONSTRUCTOR, this optimization is only
   12258              :                        useful if this doesn't store the CONSTRUCTOR into
   12259              :                        memory.  If it does, it is more efficient to just
   12260              :                        load the data from the array directly.  */
   12261            5 :                     rtx ret = expand_constructor (value, target,
   12262              :                                                   modifier, true);
   12263            5 :                     if (ret == NULL_RTX)
   12264              :                       value = NULL_TREE;
   12265              :                   }
   12266              : 
   12267              :                 if (value)
   12268            0 :                   return expand_expr (value, target, tmode, modifier);
   12269              :               }
   12270          103 :             else if (TREE_CODE (init) == CONSTRUCTOR)
   12271              :               {
   12272              :                 unsigned HOST_WIDE_INT ix;
   12273              :                 tree field, value;
   12274              : 
   12275          168 :                 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
   12276              :                                           field, value)
   12277          166 :                   if (tree_int_cst_equal (field, index))
   12278              :                     {
   12279          100 :                       if (TREE_SIDE_EFFECTS (value)
   12280          100 :                           || TREE_CODE (value) == RAW_DATA_CST)
   12281              :                         break;
   12282              : 
   12283          100 :                       if (TREE_CODE (value) == CONSTRUCTOR)
   12284              :                         {
   12285              :                           /* If VALUE is a CONSTRUCTOR, this
   12286              :                              optimization is only useful if
   12287              :                              this doesn't store the CONSTRUCTOR
   12288              :                              into memory.  If it does, it is more
   12289              :                              efficient to just load the data from
   12290              :                              the array directly.  */
   12291           95 :                           rtx ret = expand_constructor (value, target,
   12292              :                                                         modifier, true);
   12293           95 :                           if (ret == NULL_RTX)
   12294              :                             break;
   12295              :                         }
   12296              : 
   12297           62 :                       return expand_expr (fold (value), target, tmode,
   12298           62 :                                           modifier);
   12299              :                     }
   12300              :               }
   12301            1 :             else if (TREE_CODE (init) == STRING_CST)
   12302              :               {
   12303            1 :                 tree low_bound = array_ref_low_bound (exp);
   12304            1 :                 tree index1 = fold_convert_loc (loc, sizetype, treeop1);
   12305              : 
   12306              :                 /* Optimize the special case of a zero lower bound.
   12307              : 
   12308              :                    We convert the lower bound to sizetype to avoid problems
   12309              :                    with constant folding.  E.g. suppose the lower bound is
   12310              :                    1 and its mode is QI.  Without the conversion
   12311              :                       (ARRAY + (INDEX - (unsigned char)1))
   12312              :                    becomes
   12313              :                       (ARRAY + (-(unsigned char)1) + INDEX)
   12314              :                    which becomes
   12315              :                       (ARRAY + 255 + INDEX).  Oops!  */
   12316            1 :                 if (!integer_zerop (low_bound))
   12317            0 :                   index1 = size_diffop_loc (loc, index1,
   12318              :                                             fold_convert_loc (loc, sizetype,
   12319              :                                                               low_bound));
   12320              : 
   12321            1 :                 if (tree_fits_uhwi_p (index1)
   12322            2 :                     && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
   12323              :                   {
   12324            0 :                     tree char_type = TREE_TYPE (TREE_TYPE (init));
   12325            0 :                     scalar_int_mode char_mode;
   12326              : 
   12327       629888 :                     if (is_int_mode (TYPE_MODE (char_type), &char_mode)
   12328            0 :                         && GET_MODE_SIZE (char_mode) == 1)
   12329            0 :                       return gen_int_mode (TREE_STRING_POINTER (init)
   12330            0 :                                            [TREE_INT_CST_LOW (index1)],
   12331              :                                            char_mode);
   12332              :                   }
   12333              :               }
   12334              :           }
   12335              :       }
   12336       629888 :       goto normal_inner_ref;
   12337              : 
   12338      3750949 :     case COMPONENT_REF:
   12339      3750949 :       gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
   12340              :       /* Fall through.  */
   12341      4655677 :     case BIT_FIELD_REF:
   12342      4655677 :     case ARRAY_RANGE_REF:
   12343      3750949 :     normal_inner_ref:
   12344      4655677 :       {
   12345      4655677 :         machine_mode mode1, mode2;
   12346      4655677 :         poly_int64 bitsize, bitpos, bytepos;
   12347      4655677 :         tree offset;
   12348      4655677 :         int reversep, volatilep = 0;
   12349      4655677 :         tree tem
   12350      4655677 :           = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
   12351              :                                  &unsignedp, &reversep, &volatilep);
   12352      4655677 :         rtx orig_op0, memloc;
   12353      4655677 :         bool clear_mem_expr = false;
   12354      4655677 :         bool must_force_mem;
   12355              : 
   12356              :         /* If we got back the original object, something is wrong.  Perhaps
   12357              :            we are evaluating an expression too early.  In any event, don't
   12358              :            infinitely recurse.  */
   12359      4655677 :         gcc_assert (tem != exp);
   12360              : 
   12361              :         /* Make sure bitpos is not negative, this can wreak havoc later.  */
   12362      4655677 :         if (maybe_lt (bitpos, 0))
   12363              :           {
   12364          249 :             gcc_checking_assert (offset == NULL_TREE);
   12365          249 :             offset = size_int (bits_to_bytes_round_down (bitpos));
   12366          249 :             bitpos = num_trailing_bits (bitpos);
   12367              :           }
   12368              : 
   12369              :         /* If we have either an offset, a BLKmode result, or a reference
   12370              :            outside the underlying object, we must force it to memory.
   12371              :            Such a case can occur in Ada if we have unchecked conversion
   12372              :            of an expression from a scalar type to an aggregate type or
   12373              :            for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
   12374              :            passed a partially uninitialized object or a view-conversion
   12375              :            to a larger size.  */
   12376      9311354 :         must_force_mem = offset != NULL_TREE
   12377      4375338 :                          || mode1 == BLKmode
   12378      8958786 :                          || (mode == BLKmode
   12379            0 :                              && !int_mode_for_size (bitsize, 1).exists ());
   12380              : 
   12381       526904 :         const enum expand_modifier tem_modifier
   12382              :           = must_force_mem
   12383              :             ? EXPAND_MEMORY
   12384      4303109 :             : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
   12385              : 
   12386              :         /* If TEM's type is a union of variable size, pass TARGET to the inner
   12387              :            computation, since it will need a temporary and TARGET is known
   12388              :            to have to do.  This occurs in unchecked conversion in Ada.  */
   12389      4655677 :         const rtx tem_target
   12390      4655677 :           = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
   12391        36717 :             && COMPLETE_TYPE_P (TREE_TYPE (tem))
   12392        36712 :             && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
   12393            0 :             && modifier != EXPAND_STACK_PARM
   12394      4655677 :             ? target
   12395              :             : NULL_RTX;
   12396              : 
   12397      9311354 :         orig_op0 = op0
   12398      4655677 :           = expand_expr_real (tem, tem_target, VOIDmode, tem_modifier, NULL,
   12399              :                               true);
   12400              : 
   12401              :         /* If the field has a mode, we want to access it in the
   12402              :            field's mode, not the computed mode.
   12403              :            If a MEM has VOIDmode (external with incomplete type),
   12404              :            use BLKmode for it instead.  */
   12405      4655677 :         if (MEM_P (op0))
   12406              :           {
   12407      4300837 :             if (mode1 != VOIDmode)
   12408      4142971 :               op0 = adjust_address (op0, mode1, 0);
   12409       157866 :             else if (GET_MODE (op0) == VOIDmode)
   12410            0 :               op0 = adjust_address (op0, BLKmode, 0);
   12411              :           }
   12412              : 
   12413      4655677 :         mode2
   12414      4655677 :           = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
   12415              : 
   12416              :         /* See above for the rationale.  */
   12417      9311354 :         if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
   12418      2931596 :           must_force_mem = true;
   12419              : 
   12420              :         /* Handle CONCAT first.  */
   12421      4655677 :         if (GET_CODE (op0) == CONCAT && !must_force_mem)
   12422              :           {
   12423          114 :             if (known_eq (bitpos, 0)
   12424          206 :                 && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
   12425           98 :                 && COMPLEX_MODE_P (mode1)
   12426           93 :                 && COMPLEX_MODE_P (GET_MODE (op0))
   12427          393 :                 && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
   12428          186 :                     == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
   12429              :               {
   12430           93 :                 if (reversep)
   12431            0 :                   op0 = flip_storage_order (GET_MODE (op0), op0);
   12432           93 :                 if (mode1 != GET_MODE (op0))
   12433              :                   {
   12434              :                     rtx parts[2];
   12435            0 :                     for (int i = 0; i < 2; i++)
   12436              :                       {
   12437            0 :                         rtx op = read_complex_part (op0, i != 0);
   12438            0 :                         if (GET_CODE (op) == SUBREG)
   12439            0 :                           op = force_reg (GET_MODE (op), op);
   12440            0 :                         temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
   12441            0 :                         if (temp)
   12442              :                           op = temp;
   12443              :                         else
   12444              :                           {
   12445            0 :                             if (!REG_P (op) && !MEM_P (op))
   12446            0 :                               op = force_reg (GET_MODE (op), op);
   12447            0 :                             op = gen_lowpart (GET_MODE_INNER (mode1), op);
   12448              :                           }
   12449            0 :                         parts[i] = op;
   12450              :                       }
   12451            0 :                     op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
   12452              :                   }
   12453              :                 return op0;
   12454              :               }
   12455           21 :             if (known_eq (bitpos, 0)
   12456           20 :                 && known_eq (bitsize,
   12457              :                              GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
   12458           23 :                 && maybe_ne (bitsize, 0))
   12459              :               {
   12460              :                 op0 = XEXP (op0, 0);
   12461              :                 mode2 = GET_MODE (op0);
   12462              :               }
   12463           38 :             else if (known_eq (bitpos,
   12464              :                                GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
   12465            4 :                      && known_eq (bitsize,
   12466              :                                   GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
   12467            0 :                      && maybe_ne (bitpos, 0)
   12468           19 :                      && maybe_ne (bitsize, 0))
   12469              :               {
   12470            0 :                 op0 = XEXP (op0, 1);
   12471            0 :                 bitpos = 0;
   12472            0 :                 mode2 = GET_MODE (op0);
   12473              :               }
   12474              :             else
   12475              :               /* Otherwise force into memory.  */
   12476              :               must_force_mem = true;
   12477              :           }
   12478              : 
   12479              :         /* If this is a constant, put it in a register if it is a legitimate
   12480              :            constant and we don't need a memory reference.  */
   12481      4655584 :         if (CONSTANT_P (op0)
   12482           33 :             && mode2 != BLKmode
   12483           33 :             && targetm.legitimate_constant_p (mode2, op0)
   12484      4655605 :             && !must_force_mem)
   12485           21 :           op0 = force_reg (mode2, op0);
   12486              : 
   12487              :         /* Otherwise, if this is a constant, try to force it to the constant
   12488              :            pool.  Note that back-ends, e.g. MIPS, may refuse to do so if it
   12489              :            is a legitimate constant.  */
   12490      4655563 :         else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
   12491           12 :           op0 = validize_mem (memloc);
   12492              : 
   12493              :         /* Otherwise, if this is a constant or the object is not in memory
   12494              :            and need be, put it there.  */
   12495      4655551 :         else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
   12496              :           {
   12497         1095 :             machine_mode tem_mode = TYPE_MODE (TREE_TYPE (tem));
   12498         1095 :             poly_int64 size;
   12499         1095 :             if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
   12500            0 :               size = max_int_size_in_bytes (TREE_TYPE (tem));
   12501         1095 :             unsigned int align = TREE_CODE (tem) == SSA_NAME
   12502         1095 :                                  ? TYPE_ALIGN (TREE_TYPE (tem))
   12503         1095 :                                  : get_object_alignment (tem);
   12504         1095 :             if (STRICT_ALIGNMENT)
   12505              :               {
   12506              :                 /* For STRICT_ALIGNMENT targets, when we force the operand to
   12507              :                    memory, we may need to increase the alignment to meet the
   12508              :                    expectation in later RTL lowering passes.  The increased
   12509              :                    alignment is capped by MAX_SUPPORTED_STACK_ALIGNMENT.  */
   12510              :                 if (tem_mode != BLKmode)
   12511              :                   align = MAX (align, GET_MODE_ALIGNMENT (tem_mode));
   12512              :                 else
   12513              :                   align = MAX (align, TYPE_ALIGN (TREE_TYPE (tem)));
   12514              :                 align = MIN (align, (unsigned) MAX_SUPPORTED_STACK_ALIGNMENT);
   12515              :               }
   12516         1095 :             memloc = assign_stack_local (tem_mode, size, align);
   12517         1095 :             emit_move_insn (memloc, op0);
   12518         1095 :             op0 = memloc;
   12519         1095 :             clear_mem_expr = true;
   12520              :           }
   12521              : 
   12522      4655584 :         if (offset)
   12523              :           {
   12524       280339 :             machine_mode address_mode;
   12525       280339 :             rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
   12526              :                                           EXPAND_SUM);
   12527              : 
   12528       280339 :             gcc_assert (MEM_P (op0));
   12529              : 
   12530       280339 :             address_mode = get_address_mode (op0);
   12531       280339 :             if (GET_MODE (offset_rtx) != address_mode)
   12532              :               {
   12533              :                 /* We cannot be sure that the RTL in offset_rtx is valid outside
   12534              :                    of a memory address context, so force it into a register
   12535              :                    before attempting to convert it to the desired mode.  */
   12536          422 :                 offset_rtx = force_operand (offset_rtx, NULL_RTX);
   12537          422 :                 offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
   12538              :               }
   12539              : 
   12540              :             /* See the comment in expand_assignment for the rationale.  */
   12541       280339 :             if (mode1 != VOIDmode
   12542       280123 :                 && maybe_ne (bitpos, 0)
   12543        74731 :                 && maybe_gt (bitsize, 0)
   12544       354531 :                 && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
   12545       354531 :                 && multiple_p (bitpos, bitsize)
   12546       148384 :                 && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
   12547       354531 :                 && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
   12548              :               {
   12549        73834 :                 op0 = adjust_address (op0, mode1, bytepos);
   12550        73834 :                 bitpos = 0;
   12551              :               }
   12552              : 
   12553       280339 :             op0 = offset_address (op0, offset_rtx,
   12554              :                                   highest_pow2_factor (offset));
   12555              :           }
   12556              : 
   12557              :         /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
   12558              :            record its alignment as BIGGEST_ALIGNMENT.  */
   12559      4655584 :         if (MEM_P (op0)
   12560      4301944 :             && known_eq (bitpos, 0)
   12561      1455610 :             && offset != 0
   12562      4934876 :             && is_aligning_offset (offset, tem))
   12563            0 :           set_mem_align (op0, BIGGEST_ALIGNMENT);
   12564              : 
   12565              :         /* Don't forget about volatility even if this is a bitfield.  */
   12566      4655584 :         if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
   12567              :           {
   12568          528 :             if (op0 == orig_op0)
   12569          158 :               op0 = copy_rtx (op0);
   12570              : 
   12571          528 :             MEM_VOLATILE_P (op0) = 1;
   12572              :           }
   12573              : 
   12574      4655584 :         if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
   12575              :           {
   12576            6 :             if (op0 == orig_op0)
   12577            0 :               op0 = copy_rtx (op0);
   12578              : 
   12579            6 :             set_mem_align (op0, BITS_PER_UNIT);
   12580              :           }
   12581              : 
   12582              :         /* In cases where an aligned union has an unaligned object
   12583              :            as a field, we might be extracting a BLKmode value from
   12584              :            an integer-mode (e.g., SImode) object.  Handle this case
   12585              :            by doing the extract into an object as wide as the field
   12586              :            (which we know to be the width of a basic mode), then
   12587              :            storing into memory, and changing the mode to BLKmode.  */
   12588      4655584 :         if (mode1 == VOIDmode
   12589      4423780 :             || REG_P (op0) || GET_CODE (op0) == SUBREG
   12590      4144044 :             || (mode1 != BLKmode && ! direct_load[(int) mode1]
   12591        27035 :                 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
   12592        22924 :                 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
   12593              :                 && modifier != EXPAND_CONST_ADDRESS
   12594        15389 :                 && modifier != EXPAND_INITIALIZER
   12595        15389 :                 && modifier != EXPAND_MEMORY)
   12596              :             /* If the bitfield is volatile and the bitsize
   12597              :                is narrower than the access size of the bitfield,
   12598              :                we need to extract bitfields from the access.  */
   12599      4128655 :             || (volatilep && TREE_CODE (exp) == COMPONENT_REF
   12600         1511 :                 && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
   12601           10 :                 && mode1 != BLKmode
   12602           20 :                 && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
   12603              :             /* If the field isn't aligned enough to fetch as a memref,
   12604              :                fetch it as a bit field.  */
   12605      4128646 :             || (mode1 != BLKmode
   12606      4055548 :                 && (((MEM_P (op0)
   12607      4055548 :                       ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
   12608      7966204 :                         || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
   12609            0 :                       : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
   12610            0 :                         || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
   12611        75727 :                      && modifier != EXPAND_MEMORY
   12612        75727 :                      && ((modifier == EXPAND_CONST_ADDRESS
   12613        75727 :                           || modifier == EXPAND_INITIALIZER)
   12614        75727 :                          ? STRICT_ALIGNMENT
   12615        75727 :                          : targetm.slow_unaligned_access (mode1,
   12616        75727 :                                                           MEM_ALIGN (op0))))
   12617      4055548 :                     || !multiple_p (bitpos, BITS_PER_UNIT)))
   12618              :             /* If the type and the field are a constant size and the
   12619              :                size of the type isn't the same size as the bitfield,
   12620              :                we must use bitfield operations.  */
   12621     12839778 :             || (known_size_p (bitsize)
   12622      4128646 :                 && TYPE_SIZE (TREE_TYPE (exp))
   12623      4128646 :                 && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
   12624      4655584 :                 && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
   12625              :                              bitsize)))
   12626              :           {
   12627       526968 :             machine_mode ext_mode = mode;
   12628              : 
   12629       526968 :             if (ext_mode == BLKmode
   12630       526968 :                 && ! (target != 0 && MEM_P (op0)
   12631           22 :                       && MEM_P (target)
   12632           22 :                       && multiple_p (bitpos, BITS_PER_UNIT)))
   12633            4 :               ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
   12634              : 
   12635       526968 :             if (ext_mode == BLKmode)
   12636              :               {
   12637           26 :                 if (target == 0)
   12638            4 :                   target = assign_temp (type, 1, 1);
   12639              : 
   12640              :                 /* ??? Unlike the similar test a few lines below, this one is
   12641              :                    very likely obsolete.  */
   12642           26 :                 if (known_eq (bitsize, 0))
   12643              :                   return target;
   12644              : 
   12645              :                 /* In this case, BITPOS must start at a byte boundary and
   12646              :                    TARGET, if specified, must be a MEM.  */
   12647           26 :                 gcc_assert (MEM_P (op0)
   12648              :                             && (!target || MEM_P (target)));
   12649              : 
   12650           26 :                 bytepos = exact_div (bitpos, BITS_PER_UNIT);
   12651           26 :                 poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
   12652           52 :                 emit_block_move (target,
   12653              :                                  adjust_address (op0, VOIDmode, bytepos),
   12654           26 :                                  gen_int_mode (bytesize, Pmode),
   12655              :                                  (modifier == EXPAND_STACK_PARM
   12656              :                                   ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
   12657              : 
   12658           26 :                 return target;
   12659              :               }
   12660              : 
   12661              :             /* If we have nothing to extract, the result will be 0 for targets
   12662              :                with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise.  Always
   12663              :                return 0 for the sake of consistency, as reading a zero-sized
   12664              :                bitfield is valid in Ada and the value is fully specified.  */
   12665       526942 :             if (known_eq (bitsize, 0))
   12666            0 :               return const0_rtx;
   12667              : 
   12668       526942 :             op0 = validize_mem (op0);
   12669              : 
   12670       526942 :             if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
   12671        49942 :               mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12672              : 
   12673              :             /* If the result has aggregate type and the extraction is done in
   12674              :                an integral mode, then the field may be not aligned on a byte
   12675              :                boundary; in this case, if it has reverse storage order, it
   12676              :                needs to be extracted as a scalar field with reverse storage
   12677              :                order and put back into memory order afterwards.  */
   12678       526942 :             if (AGGREGATE_TYPE_P (type)
   12679         5168 :                 && GET_MODE_CLASS (ext_mode) == MODE_INT)
   12680         5086 :               reversep = TYPE_REVERSE_STORAGE_ORDER (type);
   12681              : 
   12682       526942 :             gcc_checking_assert (known_ge (bitpos, 0));
   12683      1068182 :             op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
   12684              :                                      (modifier == EXPAND_STACK_PARM
   12685              :                                       ? NULL_RTX : target),
   12686              :                                      ext_mode, ext_mode, reversep, alt_rtl);
   12687              : 
   12688              :             /* If the result has aggregate type and the mode of OP0 is an
   12689              :                integral mode then, if BITSIZE is narrower than this mode
   12690              :                and this is for big-endian data, we must put the field
   12691              :                into the high-order bits.  And we must also put it back
   12692              :                into memory order if it has been previously reversed.  */
   12693       526942 :             scalar_int_mode op0_mode;
   12694       526942 :             if (AGGREGATE_TYPE_P (type)
   12695       526942 :                 && is_int_mode (GET_MODE (op0), &op0_mode))
   12696              :               {
   12697         5086 :                 HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
   12698              : 
   12699         5086 :                 gcc_checking_assert (known_le (bitsize, size));
   12700         5086 :                 if (maybe_lt (bitsize, size)
   12701         5086 :                     && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
   12702            0 :                   op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
   12703              :                                       size - bitsize, op0, 1);
   12704              : 
   12705         5086 :                 if (reversep)
   12706            0 :                   op0 = flip_storage_order (op0_mode, op0);
   12707              :               }
   12708              : 
   12709              :             /* If the result type is BLKmode, store the data into a temporary
   12710              :                of the appropriate type, but with the mode corresponding to the
   12711              :                mode for the data we have (op0's mode).  */
   12712       526942 :             if (mode == BLKmode)
   12713              :               {
   12714            0 :                 rtx new_rtx
   12715            0 :                   = assign_stack_temp_for_type (ext_mode,
   12716            0 :                                                 GET_MODE_BITSIZE (ext_mode),
   12717              :                                                 type);
   12718            0 :                 emit_move_insn (new_rtx, op0);
   12719            0 :                 op0 = copy_rtx (new_rtx);
   12720            0 :                 PUT_MODE (op0, BLKmode);
   12721              :               }
   12722              : 
   12723              :             return op0;
   12724              :           }
   12725              : 
   12726              :         /* If the result is BLKmode, use that to access the object
   12727              :            now as well.  */
   12728      4128616 :         if (mode == BLKmode)
   12729        73072 :           mode1 = BLKmode;
   12730              : 
   12731              :         /* Get a reference to just this component.  */
   12732      4128616 :         bytepos = bits_to_bytes_round_down (bitpos);
   12733      4128616 :         if (modifier == EXPAND_CONST_ADDRESS
   12734      4128616 :             || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
   12735       164887 :           op0 = adjust_address_nv (op0, mode1, bytepos);
   12736              :         else
   12737      3963729 :           op0 = adjust_address (op0, mode1, bytepos);
   12738              : 
   12739      4128616 :         if (op0 == orig_op0)
   12740       127853 :           op0 = copy_rtx (op0);
   12741              : 
   12742              :         /* Don't set memory attributes if the base expression is
   12743              :            SSA_NAME that got expanded as a MEM or a CONSTANT.  In that case,
   12744              :            we should just honor its original memory attributes.  */
   12745      4128616 :         if (!(TREE_CODE (tem) == SSA_NAME
   12746         9531 :               && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
   12747      4119085 :           set_mem_attributes (op0, exp, 0, may_store_p);
   12748              : 
   12749      4128616 :         if (REG_P (XEXP (op0, 0)))
   12750       666375 :           mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12751              : 
   12752              :         /* If op0 is a temporary because the original expressions was forced
   12753              :            to memory, clear MEM_EXPR so that the original expression cannot
   12754              :            be marked as addressable through MEM_EXPR of the temporary.  */
   12755      4128616 :         if (clear_mem_expr)
   12756         1061 :           set_mem_expr (op0, NULL_TREE);
   12757              : 
   12758      4128616 :         MEM_VOLATILE_P (op0) |= volatilep;
   12759              : 
   12760      4128616 :         if (reversep
   12761              :             && modifier != EXPAND_MEMORY
   12762          497 :             && modifier != EXPAND_WRITE)
   12763          497 :           op0 = flip_storage_order (mode1, op0);
   12764              : 
   12765      4128616 :         op0 = EXTEND_BITINT (op0);
   12766              : 
   12767      4128616 :         if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
   12768              :             || modifier == EXPAND_CONST_ADDRESS
   12769            0 :             || modifier == EXPAND_INITIALIZER)
   12770              :           return op0;
   12771              : 
   12772            0 :         if (target == 0)
   12773            0 :           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
   12774              : 
   12775            0 :         convert_move (target, op0, unsignedp);
   12776            0 :         return target;
   12777              :       }
   12778              : 
   12779        85258 :     case OBJ_TYPE_REF:
   12780        85258 :       return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
   12781              : 
   12782      6798410 :     case CALL_EXPR:
   12783              :       /* All valid uses of __builtin_va_arg_pack () are removed during
   12784              :          inlining.  */
   12785      6798410 :       if (CALL_EXPR_VA_ARG_PACK (exp))
   12786            6 :         error ("invalid use of %<__builtin_va_arg_pack ()%>");
   12787      6798410 :       {
   12788      6798410 :         tree fndecl = get_callee_fndecl (exp), attr;
   12789              : 
   12790      6798410 :         if (fndecl
   12791              :             /* Don't diagnose the error attribute in thunks, those are
   12792              :                artificially created.  */
   12793      6611410 :             && !CALL_FROM_THUNK_P (exp)
   12794     13406194 :             && (attr = lookup_attribute ("error",
   12795      6607784 :                                          DECL_ATTRIBUTES (fndecl))) != NULL)
   12796              :           {
   12797            5 :             const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
   12798           10 :             error ("call to %qs declared with attribute error: %s",
   12799              :                    identifier_to_locale (ident),
   12800            5 :                    TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
   12801              :           }
   12802      6798410 :         if (fndecl
   12803              :             /* Don't diagnose the warning attribute in thunks, those are
   12804              :                artificially created.  */
   12805      6611410 :             && !CALL_FROM_THUNK_P (exp)
   12806     13406194 :             && (attr = lookup_attribute ("warning",
   12807      6607784 :                                          DECL_ATTRIBUTES (fndecl))) != NULL)
   12808              :           {
   12809           21 :             const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
   12810           42 :             warning_at (EXPR_LOCATION (exp),
   12811           21 :                         OPT_Wattribute_warning,
   12812              :                         "call to %qs declared with attribute warning: %s",
   12813              :                         identifier_to_locale (ident),
   12814           21 :                         TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
   12815              :           }
   12816              : 
   12817              :         /* Check for a built-in function.  */
   12818      6798410 :         if (fndecl && fndecl_built_in_p (fndecl))
   12819              :           {
   12820      2018241 :             gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
   12821      2018241 :             return expand_builtin (exp, target, subtarget, tmode, ignore);
   12822              :           }
   12823              :       }
   12824      4780169 :       temp = expand_call (exp, target, ignore);
   12825      4780167 :       return EXTEND_BITINT (temp);
   12826              : 
   12827       354165 :     case VIEW_CONVERT_EXPR:
   12828       354165 :       op0 = NULL_RTX;
   12829              : 
   12830              :       /* If we are converting to BLKmode, try to avoid an intermediate
   12831              :          temporary by fetching an inner memory reference.  */
   12832       354165 :       if (mode == BLKmode
   12833        74122 :           && poly_int_tree_p (TYPE_SIZE (type))
   12834        74122 :           && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
   12835       354165 :           && handled_component_p (treeop0))
   12836              :       {
   12837            0 :         machine_mode mode1;
   12838            0 :         poly_int64 bitsize, bitpos, bytepos;
   12839            0 :         tree offset;
   12840            0 :         int reversep, volatilep = 0;
   12841            0 :         tree tem
   12842            0 :           = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
   12843              :                                  &unsignedp, &reversep, &volatilep);
   12844              : 
   12845              :         /* ??? We should work harder and deal with non-zero offsets.  */
   12846            0 :         if (!offset
   12847            0 :             && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
   12848            0 :             && !reversep
   12849            0 :             && known_size_p (bitsize)
   12850            0 :             && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
   12851              :           {
   12852              :             /* See the normal_inner_ref case for the rationale.  */
   12853            0 :             rtx orig_op0
   12854            0 :               = expand_expr_real (tem,
   12855            0 :                                   (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
   12856            0 :                                    && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
   12857              :                                        != INTEGER_CST)
   12858            0 :                                    && modifier != EXPAND_STACK_PARM
   12859              :                                    ? target : NULL_RTX),
   12860              :                                   VOIDmode,
   12861              :                                   modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
   12862              :                                   NULL, true);
   12863              : 
   12864            0 :             if (MEM_P (orig_op0))
   12865              :               {
   12866            0 :                 op0 = orig_op0;
   12867              : 
   12868              :                 /* Get a reference to just this component.  */
   12869            0 :                 if (modifier == EXPAND_CONST_ADDRESS
   12870              :                     || modifier == EXPAND_SUM
   12871            0 :                     || modifier == EXPAND_INITIALIZER)
   12872            0 :                   op0 = adjust_address_nv (op0, mode, bytepos);
   12873              :                 else
   12874            0 :                   op0 = adjust_address (op0, mode, bytepos);
   12875              : 
   12876            0 :                 if (op0 == orig_op0)
   12877            0 :                   op0 = copy_rtx (op0);
   12878              : 
   12879            0 :                 set_mem_attributes (op0, treeop0, 0, may_store_p);
   12880            0 :                 if (REG_P (XEXP (op0, 0)))
   12881            0 :                   mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
   12882              : 
   12883            0 :                 MEM_VOLATILE_P (op0) |= volatilep;
   12884              :               }
   12885              :           }
   12886              :       }
   12887              : 
   12888            0 :       if (!op0)
   12889       428298 :         op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
   12890              :                                 NULL, inner_reference_p || mode == BLKmode);
   12891              : 
   12892              :       /* If the input and output modes are both the same, we are done.  */
   12893       354165 :       if (mode == GET_MODE (op0))
   12894              :         ;
   12895              :       /* Similarly if the output mode is BLKmode and input is a MEM,
   12896              :          adjust_address done below is all we need.  */
   12897       152839 :       else if (mode == BLKmode && MEM_P (op0))
   12898              :         ;
   12899              :       /* If neither mode is BLKmode, and both modes are the same size
   12900              :          then we can use gen_lowpart.  */
   12901              :       else if (mode != BLKmode
   12902       152805 :                && GET_MODE (op0) != BLKmode
   12903       151475 :                && known_eq (GET_MODE_PRECISION (mode),
   12904              :                             GET_MODE_PRECISION (GET_MODE (op0)))
   12905       147576 :                && !COMPLEX_MODE_P (GET_MODE (op0)))
   12906              :         {
   12907       146172 :           if (GET_CODE (op0) == SUBREG)
   12908          111 :             op0 = force_reg (GET_MODE (op0), op0);
   12909       146172 :           temp = gen_lowpart_common (mode, op0);
   12910       146172 :           if (temp)
   12911              :             op0 = temp;
   12912              :           else
   12913              :             {
   12914        28101 :               if (!REG_P (op0) && !MEM_P (op0))
   12915           18 :                 op0 = force_reg (GET_MODE (op0), op0);
   12916        28101 :               op0 = gen_lowpart (mode, op0);
   12917              :             }
   12918              :         }
   12919              :       /* If both types are integral, convert from one mode to the other.  */
   12920         6665 :       else if (INTEGRAL_TYPE_P (type)
   12921         3130 :                && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
   12922            0 :                && mode != BLKmode
   12923         6665 :                && GET_MODE (op0) != BLKmode)
   12924            0 :         op0 = convert_modes (mode, GET_MODE (op0), op0,
   12925            0 :                              TYPE_UNSIGNED (TREE_TYPE (treeop0)));
   12926              :       /* If the output type is a bit-field type, do an extraction.  */
   12927         6665 :       else if (reduce_bit_field
   12928            2 :                && mode != BLKmode
   12929            2 :                && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
   12930            0 :         return extract_bit_field (op0, TYPE_PRECISION (type), 0,
   12931            0 :                                   TYPE_UNSIGNED (type), NULL_RTX,
   12932              :                                   mode, mode, false, NULL);
   12933              :       /* If source is a complex number and destination is a
   12934              :          two-component vector with same inner type, try to use
   12935              :          vector initialization.  */
   12936         6665 :       else if ((temp = try_expand_complex_as_vector (mode, op0, target))
   12937              :                != NULL_RTX)
   12938              :         return temp;
   12939              :       /* As a last resort, spill op0 to memory, and reload it in a
   12940              :          different mode.  */
   12941         6636 :       else if (!MEM_P (op0))
   12942              :         {
   12943              :           /* If the operand is not a MEM, force it into memory.  Since we
   12944              :              are going to be changing the mode of the MEM, don't call
   12945              :              force_const_mem for constants because we don't allow pool
   12946              :              constants to change mode.  */
   12947         5296 :           tree inner_type = TREE_TYPE (treeop0);
   12948              : 
   12949         5296 :           gcc_assert (!TREE_ADDRESSABLE (exp));
   12950              : 
   12951         5296 :           if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
   12952         5292 :             target
   12953              :               = assign_stack_temp_for_type
   12954         5292 :                 (TYPE_MODE (inner_type),
   12955        10584 :                  GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
   12956              : 
   12957         5296 :           emit_move_insn (target, op0);
   12958         5296 :           op0 = target;
   12959              : 
   12960         5296 :           if (reduce_bit_field && mode != BLKmode)
   12961            2 :             return extract_bit_field (op0, TYPE_PRECISION (type), 0,
   12962            2 :                                       TYPE_UNSIGNED (type), NULL_RTX,
   12963              :                                       mode, mode, false, NULL);
   12964              :         }
   12965              : 
   12966              :       /* If OP0 is (now) a MEM, we need to deal with alignment issues.  If the
   12967              :          output type is such that the operand is known to be aligned, indicate
   12968              :          that it is.  Otherwise, we need only be concerned about alignment for
   12969              :          non-BLKmode results.  */
   12970       354134 :       if (MEM_P (op0))
   12971              :         {
   12972       128723 :           enum insn_code icode;
   12973              : 
   12974       128723 :           if (modifier != EXPAND_WRITE
   12975       128723 :               && modifier != EXPAND_MEMORY
   12976       128723 :               && !inner_reference_p
   12977       128722 :               && mode != BLKmode
   12978       183323 :               && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
   12979              :             {
   12980              :               /* If the target does have special handling for unaligned
   12981              :                  loads of mode then use them.  */
   12982        15841 :               if ((icode = optab_handler (movmisalign_optab, mode))
   12983              :                   != CODE_FOR_nothing)
   12984              :                 {
   12985         1902 :                   rtx reg;
   12986              : 
   12987         1902 :                   op0 = adjust_address (op0, mode, 0);
   12988              :                   /* We've already validated the memory, and we're creating a
   12989              :                      new pseudo destination.  The predicates really can't
   12990              :                      fail.  */
   12991         1902 :                   reg = gen_reg_rtx (mode);
   12992              : 
   12993              :                   /* Nor can the insn generator.  */
   12994         1902 :                   rtx_insn *insn = GEN_FCN (icode) (reg, op0);
   12995         1902 :                   emit_insn (insn);
   12996         1902 :                   return reg;
   12997              :                 }
   12998              :               else if (STRICT_ALIGNMENT)
   12999              :                 {
   13000              :                   poly_uint64 mode_size = GET_MODE_SIZE (mode);
   13001              :                   poly_uint64 temp_size = mode_size;
   13002              :                   if (GET_MODE (op0) != BLKmode)
   13003              :                     temp_size = upper_bound (temp_size,
   13004              :                                              GET_MODE_SIZE (GET_MODE (op0)));
   13005              :                   rtx new_rtx
   13006              :                     = assign_stack_temp_for_type (mode, temp_size, type);
   13007              :                   rtx new_with_op0_mode
   13008              :                     = adjust_address (new_rtx, GET_MODE (op0), 0);
   13009              : 
   13010              :                   gcc_assert (!TREE_ADDRESSABLE (exp));
   13011              : 
   13012              :                   if (GET_MODE (op0) == BLKmode)
   13013              :                     {
   13014              :                       rtx size_rtx = gen_int_mode (mode_size, Pmode);
   13015              :                       emit_block_move (new_with_op0_mode, op0, size_rtx,
   13016              :                                        (modifier == EXPAND_STACK_PARM
   13017              :                                         ? BLOCK_OP_CALL_PARM
   13018              :                                         : BLOCK_OP_NORMAL));
   13019              :                     }
   13020              :                   else
   13021              :                     emit_move_insn (new_with_op0_mode, op0);
   13022              : 
   13023              :                   op0 = new_rtx;
   13024              :                 }
   13025              :             }
   13026              : 
   13027       126821 :           op0 = adjust_address (op0, mode, 0);
   13028              :         }
   13029              : 
   13030              :       return op0;
   13031              : 
   13032        63628 :     case MODIFY_EXPR:
   13033        63628 :       {
   13034        63628 :         tree lhs = treeop0;
   13035        63628 :         tree rhs = treeop1;
   13036        63628 :         gcc_assert (ignore);
   13037              : 
   13038              :         /* Check for |= or &= of a bitfield of size one into another bitfield
   13039              :            of size 1.  In this case, (unless we need the result of the
   13040              :            assignment) we can do this more efficiently with a
   13041              :            test followed by an assignment, if necessary.
   13042              : 
   13043              :            ??? At this point, we can't get a BIT_FIELD_REF here.  But if
   13044              :            things change so we do, this code should be enhanced to
   13045              :            support it.  */
   13046        63628 :         if (TREE_CODE (lhs) == COMPONENT_REF
   13047        60498 :             && (TREE_CODE (rhs) == BIT_IOR_EXPR
   13048        60498 :                 || TREE_CODE (rhs) == BIT_AND_EXPR)
   13049            0 :             && TREE_OPERAND (rhs, 0) == lhs
   13050            0 :             && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
   13051            0 :             && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
   13052        63628 :             && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
   13053              :           {
   13054            0 :             rtx_code_label *label = gen_label_rtx ();
   13055            0 :             int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
   13056            0 :             profile_probability prob = profile_probability::uninitialized ();
   13057            0 :             if (value)
   13058            0 :               jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
   13059              :             else
   13060            0 :               jumpif (TREE_OPERAND (rhs, 1), label, prob);
   13061            0 :             expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value),
   13062              :                                false);
   13063            0 :             do_pending_stack_adjust ();
   13064            0 :             emit_label (label);
   13065            0 :             return const0_rtx;
   13066              :           }
   13067              : 
   13068        63628 :         expand_assignment (lhs, rhs, false);
   13069        63628 :         return const0_rtx;
   13070              :       }
   13071              : 
   13072     13229093 :     case ADDR_EXPR:
   13073     13229093 :       return expand_expr_addr_expr (exp, target, tmode, modifier);
   13074              : 
   13075       172886 :     case REALPART_EXPR:
   13076       172886 :       op0 = expand_normal (treeop0);
   13077       172886 :       return read_complex_part (op0, false);
   13078              : 
   13079       196761 :     case IMAGPART_EXPR:
   13080       196761 :       op0 = expand_normal (treeop0);
   13081       196761 :       return read_complex_part (op0, true);
   13082              : 
   13083            0 :     case RETURN_EXPR:
   13084            0 :     case LABEL_EXPR:
   13085            0 :     case GOTO_EXPR:
   13086            0 :     case SWITCH_EXPR:
   13087            0 :     case ASM_EXPR:
   13088              :       /* Expanded in cfgexpand.cc.  */
   13089            0 :       gcc_unreachable ();
   13090              : 
   13091            0 :     case TRY_CATCH_EXPR:
   13092            0 :     case CATCH_EXPR:
   13093            0 :     case EH_FILTER_EXPR:
   13094            0 :     case TRY_FINALLY_EXPR:
   13095            0 :     case EH_ELSE_EXPR:
   13096              :       /* Lowered by tree-eh.cc.  */
   13097            0 :       gcc_unreachable ();
   13098              : 
   13099            0 :     case WITH_CLEANUP_EXPR:
   13100            0 :     case CLEANUP_POINT_EXPR:
   13101            0 :     case TARGET_EXPR:
   13102            0 :     case CASE_LABEL_EXPR:
   13103            0 :     case VA_ARG_EXPR:
   13104            0 :     case BIND_EXPR:
   13105            0 :     case INIT_EXPR:
   13106            0 :     case CONJ_EXPR:
   13107            0 :     case COMPOUND_EXPR:
   13108            0 :     case PREINCREMENT_EXPR:
   13109            0 :     case PREDECREMENT_EXPR:
   13110            0 :     case POSTINCREMENT_EXPR:
   13111            0 :     case POSTDECREMENT_EXPR:
   13112            0 :     case LOOP_EXPR:
   13113            0 :     case EXIT_EXPR:
   13114            0 :     case COMPOUND_LITERAL_EXPR:
   13115              :       /* Lowered by gimplify.cc.  */
   13116            0 :       gcc_unreachable ();
   13117              : 
   13118            0 :     case FDESC_EXPR:
   13119              :       /* Function descriptors are not valid except for as
   13120              :          initialization constants, and should not be expanded.  */
   13121            0 :       gcc_unreachable ();
   13122              : 
   13123          258 :     case WITH_SIZE_EXPR:
   13124              :       /* WITH_SIZE_EXPR expands to its first argument.  The caller should
   13125              :          have pulled out the size to use in whatever context it needed.  */
   13126          258 :       return expand_expr_real (treeop0, original_target, tmode,
   13127          258 :                                modifier, alt_rtl, inner_reference_p);
   13128              : 
   13129      1851952 :     default:
   13130      1851952 :       return expand_expr_real_2 (&ops, target, tmode, modifier);
   13131              :     }
   13132              : }
   13133              : #undef EXTEND_BITINT
   13134              : 
   13135              : /* Subroutine of above: reduce EXP to the precision of TYPE (in the
   13136              :    signedness of TYPE), possibly returning the result in TARGET.
   13137              :    TYPE is known to be a partial integer type.  */
   13138              : static rtx
   13139        90049 : reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
   13140              : {
   13141        90049 :   scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
   13142        90049 :   HOST_WIDE_INT prec = TYPE_PRECISION (type);
   13143        90049 :   gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
   13144              :               && (!target || GET_MODE (target) == mode));
   13145              : 
   13146              :   /* For constant values, reduce using wide_int_to_tree. */
   13147        90049 :   if (poly_int_rtx_p (exp))
   13148              :     {
   13149            0 :       auto value = wi::to_poly_wide (exp, mode);
   13150            0 :       tree t = wide_int_to_tree (type, value);
   13151            0 :       return expand_expr (t, target, VOIDmode, EXPAND_NORMAL);
   13152              :     }
   13153        90049 :   else if (TYPE_UNSIGNED (type))
   13154              :     {
   13155        70857 :       rtx mask = immed_wide_int_const
   13156        70857 :         (wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
   13157        70857 :       return expand_and (mode, exp, mask, target);
   13158              :     }
   13159              :   else
   13160              :     {
   13161        19192 :       int count = GET_MODE_PRECISION (mode) - prec;
   13162        19192 :       exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
   13163        19192 :       return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
   13164              :     }
   13165              : }
   13166              : 
   13167              : /* Subroutine of above: returns true if OFFSET corresponds to an offset that
   13168              :    when applied to the address of EXP produces an address known to be
   13169              :    aligned more than BIGGEST_ALIGNMENT.  */
   13170              : 
   13171              : static bool
   13172       279292 : is_aligning_offset (const_tree offset, const_tree exp)
   13173              : {
   13174              :   /* Strip off any conversions.  */
   13175       297079 :   while (CONVERT_EXPR_P (offset))
   13176        17787 :     offset = TREE_OPERAND (offset, 0);
   13177              : 
   13178              :   /* We must now have a BIT_AND_EXPR with a constant that is one less than
   13179              :      power of 2 and which is larger than BIGGEST_ALIGNMENT.  */
   13180       279292 :   if (TREE_CODE (offset) != BIT_AND_EXPR
   13181            0 :       || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
   13182            0 :       || compare_tree_int (TREE_OPERAND (offset, 1),
   13183            0 :                            BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
   13184       279292 :       || !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
   13185              :     return false;
   13186              : 
   13187              :   /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
   13188              :      It must be NEGATE_EXPR.  Then strip any more conversions.  */
   13189            0 :   offset = TREE_OPERAND (offset, 0);
   13190            0 :   while (CONVERT_EXPR_P (offset))
   13191            0 :     offset = TREE_OPERAND (offset, 0);
   13192              : 
   13193            0 :   if (TREE_CODE (offset) != NEGATE_EXPR)
   13194              :     return false;
   13195              : 
   13196            0 :   offset = TREE_OPERAND (offset, 0);
   13197            0 :   while (CONVERT_EXPR_P (offset))
   13198            0 :     offset = TREE_OPERAND (offset, 0);
   13199              : 
   13200              :   /* This must now be the address of EXP.  */
   13201            0 :   return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
   13202              : }
   13203              : 
   13204              : /* Return a STRING_CST corresponding to ARG's constant initializer either
   13205              :    if it's a string constant, or, when VALREP is set, any other constant,
   13206              :    or null otherwise.
   13207              :    On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
   13208              :    within the byte string that ARG is references.  If nonnull set *MEM_SIZE
   13209              :    to the size of the byte string.  If nonnull, set *DECL to the constant
   13210              :    declaration ARG refers to.  */
   13211              : 
   13212              : static tree
   13213     15895532 : constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
   13214              :                       bool valrep = false)
   13215              : {
   13216     15895532 :   tree dummy = NULL_TREE;
   13217     15895532 :   if (!mem_size)
   13218        11133 :     mem_size = &dummy;
   13219              : 
   13220              :   /* Store the type of the original expression before conversions
   13221              :      via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
   13222              :      removed.  */
   13223     15895532 :   tree argtype = TREE_TYPE (arg);
   13224              : 
   13225     15895532 :   tree array;
   13226     15895532 :   STRIP_NOPS (arg);
   13227              : 
   13228              :   /* Non-constant index into the character array in an ARRAY_REF
   13229              :      expression or null.  */
   13230     15895532 :   tree varidx = NULL_TREE;
   13231              : 
   13232     15895532 :   poly_int64 base_off = 0;
   13233              : 
   13234     15895532 :   if (TREE_CODE (arg) == ADDR_EXPR)
   13235              :     {
   13236      6461964 :       arg = TREE_OPERAND (arg, 0);
   13237      6461964 :       tree ref = arg;
   13238      6461964 :       if (TREE_CODE (arg) == ARRAY_REF)
   13239              :         {
   13240       572915 :           tree idx = TREE_OPERAND (arg, 1);
   13241       572915 :           if (TREE_CODE (idx) != INTEGER_CST)
   13242              :             {
   13243              :               /* From a pointer (but not array) argument extract the variable
   13244              :                  index to prevent get_addr_base_and_unit_offset() from failing
   13245              :                  due to it.  Use it later to compute the non-constant offset
   13246              :                  into the string and return it to the caller.  */
   13247       168729 :               varidx = idx;
   13248       168729 :               ref = TREE_OPERAND (arg, 0);
   13249              : 
   13250       168729 :               if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
   13251              :                 return NULL_TREE;
   13252              : 
   13253        28902 :               if (!integer_zerop (array_ref_low_bound (arg)))
   13254              :                 return NULL_TREE;
   13255              : 
   13256        28154 :               if (!integer_onep (array_ref_element_size (arg)))
   13257              :                 return NULL_TREE;
   13258              :             }
   13259              :         }
   13260      6320248 :       array = get_addr_base_and_unit_offset (ref, &base_off);
   13261      6320248 :       if (!array
   13262      6272533 :           || (TREE_CODE (array) != VAR_DECL
   13263      6272533 :               && TREE_CODE (array) != CONST_DECL
   13264      3934640 :               && TREE_CODE (array) != STRING_CST))
   13265              :         return NULL_TREE;
   13266              :     }
   13267      9433568 :   else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
   13268              :     {
   13269        27056 :       tree arg0 = TREE_OPERAND (arg, 0);
   13270        27056 :       tree arg1 = TREE_OPERAND (arg, 1);
   13271              : 
   13272        27056 :       tree offset;
   13273        27056 :       tree str = string_constant (arg0, &offset, mem_size, decl);
   13274        27056 :       if (!str)
   13275              :         {
   13276        17550 :            str = string_constant (arg1, &offset, mem_size, decl);
   13277        17550 :            arg1 = arg0;
   13278              :         }
   13279              : 
   13280        17550 :       if (str)
   13281              :         {
   13282              :           /* Avoid pointers to arrays (see bug 86622).  */
   13283         9506 :           if (POINTER_TYPE_P (TREE_TYPE (arg))
   13284         9506 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
   13285         1890 :               && !(decl && !*decl)
   13286        12026 :               && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
   13287         1260 :                    && tree_fits_uhwi_p (*mem_size)
   13288         1260 :                    && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
   13289              :             return NULL_TREE;
   13290              : 
   13291         7616 :           tree type = TREE_TYPE (offset);
   13292         7616 :           arg1 = fold_convert (type, arg1);
   13293         7616 :           *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
   13294         7616 :           return str;
   13295              :         }
   13296              :       return NULL_TREE;
   13297              :     }
   13298      9406512 :   else if (TREE_CODE (arg) == SSA_NAME)
   13299              :     {
   13300      3919595 :       gimple *stmt = SSA_NAME_DEF_STMT (arg);
   13301      3919595 :       if (!is_gimple_assign (stmt))
   13302              :         return NULL_TREE;
   13303              : 
   13304      1055668 :       tree rhs1 = gimple_assign_rhs1 (stmt);
   13305      1055668 :       tree_code code = gimple_assign_rhs_code (stmt);
   13306      1055668 :       if (code == ADDR_EXPR)
   13307       237346 :         return string_constant (rhs1, ptr_offset, mem_size, decl);
   13308       818322 :       else if (code != POINTER_PLUS_EXPR)
   13309              :         return NULL_TREE;
   13310              : 
   13311       194222 :       tree offset;
   13312       194222 :       if (tree str = string_constant (rhs1, &offset, mem_size, decl))
   13313              :         {
   13314              :           /* Avoid pointers to arrays (see bug 86622).  */
   13315        23635 :           if (POINTER_TYPE_P (TREE_TYPE (rhs1))
   13316        23635 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
   13317        19700 :               && !(decl && !*decl)
   13318        39883 :               && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
   13319         8124 :                    && tree_fits_uhwi_p (*mem_size)
   13320         8124 :                    && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
   13321              :             return NULL_TREE;
   13322              : 
   13323         7237 :           tree rhs2 = gimple_assign_rhs2 (stmt);
   13324         7237 :           tree type = TREE_TYPE (offset);
   13325         7237 :           rhs2 = fold_convert (type, rhs2);
   13326         7237 :           *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
   13327         7237 :           return str;
   13328              :         }
   13329              :       return NULL_TREE;
   13330              :     }
   13331      5486917 :   else if (DECL_P (arg))
   13332              :     array = arg;
   13333              :   else
   13334              :     return NULL_TREE;
   13335              : 
   13336      8869755 :   tree offset = wide_int_to_tree (sizetype, base_off);
   13337      8869755 :   if (varidx)
   13338              :     {
   13339         2849 :       if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
   13340              :         return NULL_TREE;
   13341              : 
   13342         2138 :       gcc_assert (TREE_CODE (arg) == ARRAY_REF);
   13343         2138 :       tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
   13344         2138 :       if (TREE_CODE (chartype) != INTEGER_TYPE)
   13345              :         return NULL;
   13346              : 
   13347         1982 :       offset = fold_convert (sizetype, varidx);
   13348              :     }
   13349              : 
   13350      8868888 :   if (TREE_CODE (array) == STRING_CST)
   13351              :     {
   13352      3539344 :       *ptr_offset = fold_convert (sizetype, offset);
   13353      3539344 :       *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
   13354      3539344 :       if (decl)
   13355       760948 :         *decl = NULL_TREE;
   13356      3539344 :       gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
   13357              :                            >= TREE_STRING_LENGTH (array));
   13358              :       return array;
   13359              :     }
   13360              : 
   13361      5329544 :   tree init = ctor_for_folding (array);
   13362      5329544 :   if (!init || init == error_mark_node)
   13363              :     return NULL_TREE;
   13364              : 
   13365       163156 :   if (valrep)
   13366              :     {
   13367        58474 :       HOST_WIDE_INT cstoff;
   13368        58474 :       if (!base_off.is_constant (&cstoff))
   13369              :         return NULL_TREE;
   13370              : 
   13371              :       /* Check that the host and target are sane.  */
   13372        58474 :       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
   13373              :         return NULL_TREE;
   13374              : 
   13375        58474 :       HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
   13376        58474 :       if (typesz <= 0 || (int) typesz != typesz)
   13377              :         return NULL_TREE;
   13378              : 
   13379        58321 :       HOST_WIDE_INT size = typesz;
   13380        58321 :       if (VAR_P (array)
   13381        58309 :           && DECL_SIZE_UNIT (array)
   13382       116630 :           && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
   13383              :         {
   13384        58309 :           size = tree_to_shwi (DECL_SIZE_UNIT (array));
   13385        58309 :           gcc_checking_assert (size >= typesz);
   13386              :         }
   13387              : 
   13388              :       /* If value representation was requested convert the initializer
   13389              :          for the whole array or object into a string of bytes forming
   13390              :          its value representation and return it.  */
   13391        58321 :       unsigned char *bytes = XNEWVEC (unsigned char, size);
   13392        58321 :       int r = native_encode_initializer (init, bytes, size);
   13393        58321 :       if (r < typesz)
   13394              :         {
   13395           60 :           XDELETEVEC (bytes);
   13396           60 :           return NULL_TREE;
   13397              :         }
   13398              : 
   13399        58261 :       if (r < size)
   13400            0 :         memset (bytes + r, '\0', size - r);
   13401              : 
   13402        58261 :       const char *p = reinterpret_cast<const char *>(bytes);
   13403        58261 :       init = build_string_literal (size, p, char_type_node);
   13404        58261 :       init = TREE_OPERAND (init, 0);
   13405        58261 :       init = TREE_OPERAND (init, 0);
   13406        58261 :       XDELETE (bytes);
   13407              : 
   13408        58261 :       *mem_size = size_int (TREE_STRING_LENGTH (init));
   13409        58261 :       *ptr_offset = wide_int_to_tree (ssizetype, base_off);
   13410              : 
   13411        58261 :       if (decl)
   13412            0 :         *decl = array;
   13413              : 
   13414              :       return init;
   13415              :     }
   13416              : 
   13417       104682 :   if (TREE_CODE (init) == CONSTRUCTOR)
   13418              :     {
   13419              :       /* Convert the 64-bit constant offset to a wider type to avoid
   13420              :          overflow and use it to obtain the initializer for the subobject
   13421              :          it points into.  */
   13422        83941 :       offset_int wioff;
   13423        83941 :       if (!base_off.is_constant (&wioff))
   13424          155 :         return NULL_TREE;
   13425              : 
   13426        83941 :       wioff *= BITS_PER_UNIT;
   13427        83941 :       if (!wi::fits_uhwi_p (wioff))
   13428              :         return NULL_TREE;
   13429              : 
   13430        83833 :       base_off = wioff.to_uhwi ();
   13431        83833 :       unsigned HOST_WIDE_INT fieldoff = 0;
   13432        83833 :       init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
   13433              :                                   &fieldoff);
   13434        83833 :       if (!init || init == error_mark_node)
   13435              :         return NULL_TREE;
   13436              : 
   13437        83786 :       HOST_WIDE_INT cstoff;
   13438        83786 :       if (!base_off.is_constant (&cstoff))
   13439              :         return NULL_TREE;
   13440              : 
   13441        83786 :       cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
   13442        83786 :       tree off = build_int_cst (sizetype, cstoff);
   13443        83786 :       if (varidx)
   13444         1122 :         offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
   13445              :       else
   13446              :         offset = off;
   13447              :     }
   13448              : 
   13449       104527 :   *ptr_offset = offset;
   13450              : 
   13451       104527 :   tree inittype = TREE_TYPE (init);
   13452              : 
   13453       104527 :   if (TREE_CODE (init) == INTEGER_CST
   13454       104527 :       && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
   13455         1116 :           || TYPE_MAIN_VARIANT (inittype) == char_type_node))
   13456              :     {
   13457              :       /* Check that the host and target are sane.  */
   13458          903 :       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
   13459              :         return NULL_TREE;
   13460              : 
   13461              :       /* For a reference to (address of) a single constant character,
   13462              :          store the native representation of the character in CHARBUF.
   13463              :          If the reference is to an element of an array or a member
   13464              :          of a struct, only consider narrow characters until ctors
   13465              :          for wide character arrays are transformed to STRING_CSTs
   13466              :          like those for narrow arrays.  */
   13467          903 :       unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
   13468          903 :       int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
   13469          903 :       if (len > 0)
   13470              :         {
   13471              :           /* Construct a string literal with elements of INITTYPE and
   13472              :              the representation above.  Then strip
   13473              :              the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST.  */
   13474          903 :           init = build_string_literal (len, (char *)charbuf, inittype);
   13475          903 :           init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
   13476              :         }
   13477              :     }
   13478              : 
   13479       104527 :   tree initsize = TYPE_SIZE_UNIT (inittype);
   13480              : 
   13481       104527 :   if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
   13482              :     {
   13483              :       /* Fold an empty/zero constructor for an implicitly initialized
   13484              :          object or subobject into the empty string.  */
   13485              : 
   13486              :       /* Determine the character type from that of the original
   13487              :          expression.  */
   13488         9337 :       tree chartype = argtype;
   13489         9337 :       if (POINTER_TYPE_P (chartype))
   13490         9330 :         chartype = TREE_TYPE (chartype);
   13491        14958 :       while (TREE_CODE (chartype) == ARRAY_TYPE)
   13492         5621 :         chartype = TREE_TYPE (chartype);
   13493              : 
   13494         9337 :       if (INTEGRAL_TYPE_P (chartype)
   13495         9337 :           && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
   13496              :         {
   13497              :           /* Convert a char array to an empty STRING_CST having an array
   13498              :              of the expected type and size.  */
   13499         9133 :           if (!initsize)
   13500         3090 :             initsize = integer_zero_node;
   13501         6043 :           else if (!tree_fits_uhwi_p (initsize))
   13502              :             return NULL_TREE;
   13503              : 
   13504         9127 :           unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
   13505         9127 :           if (size > (unsigned HOST_WIDE_INT) INT_MAX)
   13506              :             return NULL_TREE;
   13507              : 
   13508         9127 :           init = build_string_literal (size, NULL, chartype, size);
   13509         9127 :           init = TREE_OPERAND (init, 0);
   13510         9127 :           init = TREE_OPERAND (init, 0);
   13511              : 
   13512         9127 :           *ptr_offset = integer_zero_node;
   13513              :         }
   13514              :     }
   13515              : 
   13516       104521 :   if (decl)
   13517        54367 :     *decl = array;
   13518              : 
   13519       104521 :   if (TREE_CODE (init) != STRING_CST)
   13520              :     return NULL_TREE;
   13521              : 
   13522        72333 :   *mem_size = initsize;
   13523              : 
   13524        72333 :   gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
   13525              : 
   13526              :   return init;
   13527              : }
   13528              : 
   13529              : /* Return STRING_CST if an ARG corresponds to a string constant or zero
   13530              :    if it doesn't.  If we return nonzero, set *PTR_OFFSET to the (possibly
   13531              :    non-constant) offset in bytes within the string that ARG is accessing.
   13532              :    If MEM_SIZE is non-zero the storage size of the memory is returned.
   13533              :    If DECL is non-zero the constant declaration is returned if available.  */
   13534              : 
   13535              : tree
   13536     11210266 : string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
   13537              : {
   13538     11210266 :   return constant_byte_string (arg, ptr_offset, mem_size, decl, false);
   13539              : }
   13540              : 
   13541              : /* Similar to string_constant, return a STRING_CST corresponding
   13542              :    to the value representation of the first argument if it's
   13543              :    a constant.  */
   13544              : 
   13545              : tree
   13546      4685266 : byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
   13547              : {
   13548      4685266 :   return constant_byte_string (arg, ptr_offset, mem_size, decl, true);
   13549              : }
   13550              : 
   13551              : /* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
   13552              :    is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
   13553              :    for C2 > 0 to x & C3 == C2
   13554              :    for C2 < 0 to x & C3 == (C2 & C3).  */
   13555              : enum tree_code
   13556           35 : maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
   13557              : {
   13558           35 :   gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
   13559           35 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13560           35 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13561           35 :   tree type = TREE_TYPE (*arg0);
   13562           35 :   scalar_int_mode mode;
   13563           35 :   if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
   13564              :     return code;
   13565           70 :   if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
   13566           35 :       || TYPE_PRECISION (type) <= 1
   13567           35 :       || TYPE_UNSIGNED (type)
   13568              :       /* Signed x % c == 0 should have been optimized into unsigned modulo
   13569              :          earlier.  */
   13570           35 :       || integer_zerop (*arg1)
   13571              :       /* If c is known to be non-negative, modulo will be expanded as unsigned
   13572              :          modulo.  */
   13573           70 :       || get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1)
   13574              :     return code;
   13575              : 
   13576              :   /* x % c == d where d < 0 && d <= -c should be always false.  */
   13577           35 :   if (tree_int_cst_sgn (*arg1) == -1
   13578           51 :       && -wi::to_widest (treeop1) >= wi::to_widest (*arg1))
   13579              :     return code;
   13580              : 
   13581           35 :   int prec = TYPE_PRECISION (type);
   13582           35 :   wide_int w = wi::to_wide (treeop1) - 1;
   13583           35 :   w |= wi::shifted_mask (0, prec - 1, true, prec);
   13584           35 :   tree c3 = wide_int_to_tree (type, w);
   13585           35 :   tree c4 = *arg1;
   13586           35 :   if (tree_int_cst_sgn (*arg1) == -1)
   13587           16 :     c4 = wide_int_to_tree (type, w & wi::to_wide (*arg1));
   13588              : 
   13589           35 :   rtx op0 = expand_normal (treeop0);
   13590           35 :   treeop0 = make_tree (TREE_TYPE (treeop0), op0);
   13591              : 
   13592           35 :   bool speed_p = optimize_insn_for_speed_p ();
   13593              : 
   13594           35 :   do_pending_stack_adjust ();
   13595              : 
   13596           35 :   location_t loc = gimple_location (stmt);
   13597           35 :   struct separate_ops ops;
   13598           35 :   ops.code = TRUNC_MOD_EXPR;
   13599           35 :   ops.location = loc;
   13600           35 :   ops.type = TREE_TYPE (treeop0);
   13601           35 :   ops.op0 = treeop0;
   13602           35 :   ops.op1 = treeop1;
   13603           35 :   ops.op2 = NULL_TREE;
   13604           35 :   start_sequence ();
   13605           35 :   rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13606              :                                 EXPAND_NORMAL);
   13607           35 :   rtx_insn *moinsns = end_sequence ();
   13608              : 
   13609           35 :   unsigned mocost = seq_cost (moinsns, speed_p);
   13610           35 :   mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
   13611           35 :   mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
   13612              : 
   13613           35 :   ops.code = BIT_AND_EXPR;
   13614           35 :   ops.location = loc;
   13615           35 :   ops.type = TREE_TYPE (treeop0);
   13616           35 :   ops.op0 = treeop0;
   13617           35 :   ops.op1 = c3;
   13618           35 :   ops.op2 = NULL_TREE;
   13619           35 :   start_sequence ();
   13620           35 :   rtx mur = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13621              :                                 EXPAND_NORMAL);
   13622           35 :   rtx_insn *muinsns = end_sequence ();
   13623              : 
   13624           35 :   unsigned mucost = seq_cost (muinsns, speed_p);
   13625           35 :   mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
   13626           35 :   mucost += rtx_cost (expand_normal (c4), mode, EQ, 1, speed_p);
   13627              : 
   13628           35 :   if (mocost <= mucost)
   13629              :     {
   13630            0 :       emit_insn (moinsns);
   13631            0 :       *arg0 = make_tree (TREE_TYPE (*arg0), mor);
   13632            0 :       return code;
   13633              :     }
   13634              : 
   13635           35 :   emit_insn (muinsns);
   13636           35 :   *arg0 = make_tree (TREE_TYPE (*arg0), mur);
   13637           35 :   *arg1 = c4;
   13638           35 :   return code;
   13639           35 : }
   13640              : 
   13641              : /* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
   13642              :    If C1 is odd to:
   13643              :    (X - C2) * C3 <= C4 (or >), where
   13644              :    C3 is modular multiplicative inverse of C1 and 1<<prec and
   13645              :    C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
   13646              :    if C2 > ((1<<prec) - 1) % C1).
   13647              :    If C1 is even, S = ctz (C1) and C2 is 0, use
   13648              :    ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
   13649              :    inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
   13650              : 
   13651              :    For signed (X % C1) == 0 if C1 is odd to (all operations in it
   13652              :    unsigned):
   13653              :    (X * C3) + C4 <= 2 * C4, where
   13654              :    C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
   13655              :    C4 is ((1<<(prec - 1) - 1) / C1).
   13656              :    If C1 is even, S = ctz(C1), use
   13657              :    ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
   13658              :    where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
   13659              :    and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
   13660              : 
   13661              :    See the Hacker's Delight book, section 10-17.  */
   13662              : enum tree_code
   13663      3370257 : maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
   13664              : {
   13665      3370257 :   gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
   13666      3370257 :   gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
   13667              : 
   13668      3370257 :   if (optimize < 2)
   13669              :     return code;
   13670              : 
   13671      2555535 :   gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
   13672      2555535 :   if (stmt == NULL)
   13673              :     return code;
   13674              : 
   13675         2108 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13676         2108 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13677         2108 :   if (TREE_CODE (treeop0) != SSA_NAME
   13678         2006 :       || TREE_CODE (treeop1) != INTEGER_CST
   13679              :       /* Don't optimize the undefined behavior case x % 0;
   13680              :          x % 1 should have been optimized into zero, punt if
   13681              :          it makes it here for whatever reason;
   13682              :          x % -c should have been optimized into x % c.  */
   13683         1647 :       || compare_tree_int (treeop1, 2) <= 0
   13684              :       /* Likewise x % c == d where d >= c should be always false.  */
   13685         3679 :       || tree_int_cst_le (treeop1, *arg1))
   13686              :     return code;
   13687              : 
   13688              :   /* Unsigned x % pow2 is handled right already, for signed
   13689              :      modulo handle it in maybe_optimize_pow2p_mod_cmp.  */
   13690         1571 :   if (integer_pow2p (treeop1))
   13691           35 :     return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
   13692              : 
   13693         1536 :   tree type = TREE_TYPE (*arg0);
   13694         1536 :   scalar_int_mode mode;
   13695         1536 :   if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
   13696              :     return code;
   13697         3072 :   if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
   13698         1536 :       || TYPE_PRECISION (type) <= 1)
   13699              :     return code;
   13700              : 
   13701         1536 :   signop sgn = UNSIGNED;
   13702              :   /* If both operands are known to have the sign bit clear, handle
   13703              :      even the signed modulo case as unsigned.  treeop1 is always
   13704              :      positive >= 2, checked above.  */
   13705         1536 :   if (!TYPE_UNSIGNED (type)
   13706         1536 :       && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) != 1)
   13707              :     sgn = SIGNED;
   13708              : 
   13709         1536 :   if (!TYPE_UNSIGNED (type))
   13710              :     {
   13711         1308 :       if (tree_int_cst_sgn (*arg1) == -1)
   13712              :         return code;
   13713         1301 :       type = unsigned_type_for (type);
   13714         1301 :       if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
   13715              :         return code;
   13716              :     }
   13717              : 
   13718         1529 :   int prec = TYPE_PRECISION (type);
   13719         1529 :   wide_int w = wi::to_wide (treeop1);
   13720         1529 :   int shift = wi::ctz (w);
   13721              :   /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
   13722              :      C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
   13723              :      If C1 is odd, we can handle all cases by subtracting
   13724              :      C4 below.  We could handle even the even C1 and C2 > -1U % C1 cases
   13725              :      e.g. by testing for overflow on the subtraction, punt on that for now
   13726              :      though.  */
   13727         1529 :   if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
   13728              :     {
   13729          186 :       if (sgn == SIGNED)
   13730          171 :         return code;
   13731           26 :       wide_int x = wi::umod_trunc (wi::mask (prec, false, prec), w);
   13732           26 :       if (wi::gtu_p (wi::to_wide (*arg1), x))
   13733           11 :         return code;
   13734           26 :     }
   13735              : 
   13736         1358 :   imm_use_iterator imm_iter;
   13737         1358 :   use_operand_p use_p;
   13738         7005 :   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
   13739              :     {
   13740         5657 :       gimple *use_stmt = USE_STMT (use_p);
   13741              :       /* Punt if treeop0 is used in the same bb in a division
   13742              :          or another modulo with the same divisor.  We should expect
   13743              :          the division and modulo combined together.  */
   13744        11217 :       if (use_stmt == stmt
   13745         5657 :           || gimple_bb (use_stmt) != gimple_bb (stmt))
   13746         5560 :         continue;
   13747           97 :       if (!is_gimple_assign (use_stmt)
   13748           97 :           || (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR
   13749           81 :               && gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR))
   13750           72 :         continue;
   13751           25 :       if (gimple_assign_rhs1 (use_stmt) != treeop0
   13752           25 :           || !operand_equal_p (gimple_assign_rhs2 (use_stmt), treeop1, 0))
   13753           15 :         continue;
   13754           10 :       return code;
   13755           10 :     }
   13756              : 
   13757         1348 :   w = wi::lrshift (w, shift);
   13758         1348 :   wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
   13759         1348 :   wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
   13760         1348 :   wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
   13761         1348 :   tree c3 = wide_int_to_tree (type, m);
   13762         1348 :   tree c5 = NULL_TREE;
   13763         1348 :   wide_int d, e;
   13764         1348 :   if (sgn == UNSIGNED)
   13765              :     {
   13766         1011 :       d = wi::divmod_trunc (wi::mask (prec, false, prec), w, UNSIGNED, &e);
   13767              :       /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
   13768              :          otherwise use < or subtract one from C4.  E.g. for
   13769              :          x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
   13770              :          x % 3U == 1 already needs to be
   13771              :          (x - 1) * 0xaaaaaaabU <= 0x55555554.  */
   13772         1011 :       if (!shift && wi::gtu_p (wi::to_wide (*arg1), e))
   13773           16 :         d -= 1;
   13774         1011 :       if (shift)
   13775          442 :         d = wi::lrshift (d, shift);
   13776              :     }
   13777              :   else
   13778              :     {
   13779          337 :       e = wi::udiv_trunc (wi::mask (prec - 1, false, prec), w);
   13780          337 :       if (!shift)
   13781          142 :         d = wi::lshift (e, 1);
   13782              :       else
   13783              :         {
   13784          195 :           e = wi::bit_and (e, wi::mask (shift, true, prec));
   13785          195 :           d = wi::lrshift (e, shift - 1);
   13786              :         }
   13787          337 :       c5 = wide_int_to_tree (type, e);
   13788              :     }
   13789         1348 :   tree c4 = wide_int_to_tree (type, d);
   13790              : 
   13791         1348 :   rtx op0 = expand_normal (treeop0);
   13792         1348 :   treeop0 = make_tree (TREE_TYPE (treeop0), op0);
   13793              : 
   13794         1348 :   bool speed_p = optimize_insn_for_speed_p ();
   13795              : 
   13796         1348 :   do_pending_stack_adjust ();
   13797              : 
   13798         1348 :   location_t loc = gimple_location (stmt);
   13799         1348 :   struct separate_ops ops;
   13800         1348 :   ops.code = TRUNC_MOD_EXPR;
   13801         1348 :   ops.location = loc;
   13802         1348 :   ops.type = TREE_TYPE (treeop0);
   13803         1348 :   ops.op0 = treeop0;
   13804         1348 :   ops.op1 = treeop1;
   13805         1348 :   ops.op2 = NULL_TREE;
   13806         1348 :   start_sequence ();
   13807         1348 :   rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
   13808              :                                 EXPAND_NORMAL);
   13809         1348 :   rtx_insn *moinsns = end_sequence ();
   13810              : 
   13811         1348 :   unsigned mocost = seq_cost (moinsns, speed_p);
   13812         1348 :   mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
   13813         1348 :   mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
   13814              : 
   13815         1348 :   tree t = fold_convert_loc (loc, type, treeop0);
   13816         1348 :   if (!integer_zerop (*arg1))
   13817           39 :     t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
   13818         1348 :   t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
   13819         1348 :   if (sgn == SIGNED)
   13820          337 :     t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
   13821         1348 :   if (shift)
   13822              :     {
   13823          637 :       tree s = build_int_cst (integer_type_node, shift);
   13824          637 :       t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
   13825              :     }
   13826              : 
   13827         1348 :   start_sequence ();
   13828         1348 :   rtx mur = expand_normal (t);
   13829         1348 :   rtx_insn *muinsns = end_sequence ();
   13830              : 
   13831         1348 :   unsigned mucost = seq_cost (muinsns, speed_p);
   13832         1348 :   mucost += rtx_cost (mur, mode, LE, 0, speed_p);
   13833         1348 :   mucost += rtx_cost (expand_normal (c4), mode, LE, 1, speed_p);
   13834              : 
   13835         1348 :   if (mocost <= mucost)
   13836              :     {
   13837          223 :       emit_insn (moinsns);
   13838          223 :       *arg0 = make_tree (TREE_TYPE (*arg0), mor);
   13839          223 :       return code;
   13840              :     }
   13841              : 
   13842         1125 :   emit_insn (muinsns);
   13843         1125 :   *arg0 = make_tree (type, mur);
   13844         1125 :   *arg1 = c4;
   13845         1125 :   return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
   13846         2877 : }
   13847              : 
   13848              : /* Optimize x - y < 0 into x < 0 if x - y has undefined overflow.  */
   13849              : 
   13850              : void
   13851       241142 : maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
   13852              : {
   13853       241142 :   gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
   13854              :                        || code == LT_EXPR || code == LE_EXPR);
   13855       241142 :   gcc_checking_assert (integer_zerop (*arg1));
   13856              : 
   13857       241142 :   if (!optimize)
   13858              :     return;
   13859              : 
   13860       207255 :   gimple *stmt = get_def_for_expr (*arg0, MINUS_EXPR);
   13861       207255 :   if (stmt == NULL)
   13862              :     return;
   13863              : 
   13864         1371 :   tree treeop0 = gimple_assign_rhs1 (stmt);
   13865         1371 :   tree treeop1 = gimple_assign_rhs2 (stmt);
   13866         1371 :   if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
   13867              :     return;
   13868              : 
   13869         1274 :   *arg0 = treeop0;
   13870         1274 :   *arg1 = treeop1;
   13871              : }
   13872              : 
   13873              : 
   13874              : /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
   13875              :    a single bit equality/inequality test, returns where the result is located.  */
   13876              : 
   13877              : static rtx
   13878         9845 : expand_single_bit_test (location_t loc, enum tree_code code,
   13879              :                         tree inner, int bitnum,
   13880              :                         tree result_type, rtx target,
   13881              :                         machine_mode mode)
   13882              : {
   13883         9845 :   gcc_assert (code == NE_EXPR || code == EQ_EXPR);
   13884              : 
   13885         9845 :   tree type = TREE_TYPE (inner);
   13886         9845 :   scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
   13887         9845 :   int ops_unsigned;
   13888         9845 :   tree signed_type, unsigned_type, intermediate_type;
   13889         9845 :   gimple *inner_def;
   13890              : 
   13891              :   /* First, see if we can fold the single bit test into a sign-bit
   13892              :      test.  */
   13893         9845 :   if (bitnum == TYPE_PRECISION (type) - 1
   13894         9845 :       && type_has_mode_precision_p (type))
   13895              :     {
   13896          241 :       tree stype = signed_type_for (type);
   13897          444 :       tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
   13898              :                                   result_type,
   13899              :                                   fold_convert_loc (loc, stype, inner),
   13900              :                                   build_int_cst (stype, 0));
   13901          241 :       return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
   13902              :     }
   13903              : 
   13904              :   /* Otherwise we have (A & C) != 0 where C is a single bit,
   13905              :      convert that into ((A >> C2) & 1).  Where C2 = log2(C).
   13906              :      Similarly for (A & C) == 0.  */
   13907              : 
   13908              :   /* If INNER is a right shift of a constant and it plus BITNUM does
   13909              :      not overflow, adjust BITNUM and INNER.  */
   13910         9604 :   if ((inner_def = get_def_for_expr (inner, RSHIFT_EXPR))
   13911           61 :        && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
   13912           16 :        && bitnum < TYPE_PRECISION (type)
   13913         9620 :        && wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (inner_def)),
   13914         9604 :                      TYPE_PRECISION (type) - bitnum))
   13915              :     {
   13916           16 :       bitnum += tree_to_uhwi (gimple_assign_rhs2 (inner_def));
   13917           16 :       inner = gimple_assign_rhs1 (inner_def);
   13918              :     }
   13919              : 
   13920              :   /* If we are going to be able to omit the AND below, we must do our
   13921              :      operations as unsigned.  If we must use the AND, we have a choice.
   13922              :      Normally unsigned is faster, but for some machines signed is.  */
   13923         9604 :   ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
   13924              :                   && !flag_syntax_only) ? 0 : 1;
   13925              : 
   13926         9604 :   signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
   13927         9604 :   unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
   13928         9604 :   intermediate_type = ops_unsigned ? unsigned_type : signed_type;
   13929         9604 :   inner = fold_convert_loc (loc, intermediate_type, inner);
   13930              : 
   13931         9604 :   rtx inner0 = expand_expr (inner, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   13932              : 
   13933         9604 :   if (CONST_SCALAR_INT_P (inner0))
   13934              :     {
   13935            0 :       wide_int t = rtx_mode_t (inner0, operand_mode);
   13936            0 :       bool setp = (wi::lrshift (t, bitnum) & 1) != 0;
   13937            0 :       return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
   13938            0 :     }
   13939         9604 :   int bitpos = bitnum;
   13940              : 
   13941         9604 :   if (BYTES_BIG_ENDIAN)
   13942              :     bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
   13943              : 
   13944         9604 :   inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
   13945              :                               operand_mode, mode, 0, NULL);
   13946              : 
   13947         9604 :   if (code == EQ_EXPR)
   13948         2703 :     inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
   13949              :                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
   13950         9604 :   if (GET_MODE (inner0) != mode)
   13951              :     {
   13952            0 :       rtx t = gen_reg_rtx (mode);
   13953            0 :       convert_move (t, inner0, 0);
   13954            0 :       return t;
   13955              :     }
   13956              :   return inner0;
   13957              : }
   13958              : 
   13959              : /* Generate code to calculate OPS, and exploded expression
   13960              :    using a store-flag instruction and return an rtx for the result.
   13961              :    OPS reflects a comparison.
   13962              : 
   13963              :    If TARGET is nonzero, store the result there if convenient.
   13964              : 
   13965              :    Return zero if there is no suitable set-flag instruction
   13966              :    available on this machine.
   13967              : 
   13968              :    Once expand_expr has been called on the arguments of the comparison,
   13969              :    we are committed to doing the store flag, since it is not safe to
   13970              :    re-evaluate the expression.  We emit the store-flag insn by calling
   13971              :    emit_store_flag, but only expand the arguments if we have a reason
   13972              :    to believe that emit_store_flag will be successful.  If we think that
   13973              :    it will, but it isn't, we have to simulate the store-flag with a
   13974              :    set/jump/set sequence.  */
   13975              : 
   13976              : static rtx
   13977       639871 : do_store_flag (const_sepops ops, rtx target, machine_mode mode)
   13978              : {
   13979       639871 :   enum rtx_code code;
   13980       639871 :   tree arg0, arg1, type;
   13981       639871 :   machine_mode operand_mode;
   13982       639871 :   int unsignedp;
   13983       639871 :   rtx op0, op1;
   13984       639871 :   rtx subtarget = target;
   13985       639871 :   location_t loc = ops->location;
   13986       639871 :   unsigned HOST_WIDE_INT nunits;
   13987              : 
   13988       639871 :   arg0 = ops->op0;
   13989       639871 :   arg1 = ops->op1;
   13990              : 
   13991              :   /* Don't crash if the comparison was erroneous.  */
   13992       639871 :   if (arg0 == error_mark_node || arg1 == error_mark_node)
   13993            0 :     return const0_rtx;
   13994              : 
   13995       639871 :   type = TREE_TYPE (arg0);
   13996       639871 :   operand_mode = TYPE_MODE (type);
   13997       639871 :   unsignedp = TYPE_UNSIGNED (type);
   13998              : 
   13999              :   /* We won't bother with BLKmode store-flag operations because it would mean
   14000              :      passing a lot of information to emit_store_flag.  */
   14001       639871 :   if (operand_mode == BLKmode)
   14002              :     return 0;
   14003              : 
   14004              :   /* We won't bother with store-flag operations involving function pointers
   14005              :      when function pointers must be canonicalized before comparisons.  */
   14006       639871 :   if (targetm.have_canonicalize_funcptr_for_compare ()
   14007       639871 :       && ((POINTER_TYPE_P (TREE_TYPE (arg0))
   14008            0 :            && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
   14009            0 :           || (POINTER_TYPE_P (TREE_TYPE (arg1))
   14010            0 :               && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
   14011              :     return 0;
   14012              : 
   14013       639871 :   STRIP_NOPS (arg0);
   14014       639871 :   STRIP_NOPS (arg1);
   14015              : 
   14016              :   /* For vector typed comparisons emit code to generate the desired
   14017              :      all-ones or all-zeros mask.  */
   14018       639871 :   if (VECTOR_TYPE_P (ops->type))
   14019              :     {
   14020        26203 :       tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
   14021        26203 :       if (VECTOR_BOOLEAN_TYPE_P (ops->type)
   14022        52406 :           && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
   14023        26203 :         return expand_vec_cmp_expr (ops->type, ifexp, target);
   14024              :       else
   14025            0 :         gcc_unreachable ();
   14026              :     }
   14027              : 
   14028              :   /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
   14029              :      into (x - C2) * C3 < C4.  */
   14030       613668 :   if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
   14031       413705 :       && TREE_CODE (arg0) == SSA_NAME
   14032       413130 :       && TREE_CODE (arg1) == INTEGER_CST)
   14033              :     {
   14034       246994 :       enum tree_code new_code = maybe_optimize_mod_cmp (ops->code,
   14035              :                                                         &arg0, &arg1);
   14036       246994 :       if (new_code != ops->code)
   14037              :         {
   14038          107 :           struct separate_ops nops = *ops;
   14039          107 :           nops.code = new_code;
   14040          107 :           nops.op0 = arg0;
   14041          107 :           nops.op1 = arg1;
   14042          107 :           nops.type = TREE_TYPE (arg0);
   14043          107 :           return do_store_flag (&nops, target, mode);
   14044              :         }
   14045              :     }
   14046              : 
   14047              :   /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow.  */
   14048       613561 :   if (!unsignedp
   14049       441887 :       && (ops->code == LT_EXPR || ops->code == LE_EXPR
   14050       441887 :           || ops->code == GT_EXPR || ops->code == GE_EXPR)
   14051       126692 :       && integer_zerop (arg1)
   14052       652114 :       && TREE_CODE (arg0) == SSA_NAME)
   14053        38549 :     maybe_optimize_sub_cmp_0 (ops->code, &arg0, &arg1);
   14054              : 
   14055              :   /* Get the rtx comparison code to use.  We know that EXP is a comparison
   14056              :      operation of some type.  Some comparisons against 1 and -1 can be
   14057              :      converted to comparisons with zero.  Do so here so that the tests
   14058              :      below will be aware that we have a comparison with zero.   These
   14059              :      tests will not catch constants in the first operand, but constants
   14060              :      are rarely passed as the first operand.  */
   14061              : 
   14062       613561 :   switch (ops->code)
   14063              :     {
   14064              :     case EQ_EXPR:
   14065              :       code = EQ;
   14066              :       break;
   14067       235978 :     case NE_EXPR:
   14068       235978 :       code = NE;
   14069       235978 :       break;
   14070        41339 :     case LT_EXPR:
   14071        41339 :       if (integer_onep (arg1))
   14072            0 :         arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
   14073              :       else
   14074        41339 :         code = unsignedp ? LTU : LT;
   14075              :       break;
   14076        33404 :     case LE_EXPR:
   14077        33404 :       if (! unsignedp && integer_all_onesp (arg1))
   14078            0 :         arg1 = integer_zero_node, code = LT;
   14079              :       else
   14080        33404 :         code = unsignedp ? LEU : LE;
   14081              :       break;
   14082        52981 :     case GT_EXPR:
   14083        52981 :       if (! unsignedp && integer_all_onesp (arg1))
   14084            0 :         arg1 = integer_zero_node, code = GE;
   14085              :       else
   14086        52981 :         code = unsignedp ? GTU : GT;
   14087              :       break;
   14088        47640 :     case GE_EXPR:
   14089        47640 :       if (integer_onep (arg1))
   14090            0 :         arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
   14091              :       else
   14092        47640 :         code = unsignedp ? GEU : GE;
   14093              :       break;
   14094              : 
   14095         1030 :     case UNORDERED_EXPR:
   14096         1030 :       code = UNORDERED;
   14097         1030 :       break;
   14098          720 :     case ORDERED_EXPR:
   14099          720 :       code = ORDERED;
   14100          720 :       break;
   14101          536 :     case UNLT_EXPR:
   14102          536 :       code = UNLT;
   14103          536 :       break;
   14104        11137 :     case UNLE_EXPR:
   14105        11137 :       code = UNLE;
   14106        11137 :       break;
   14107         1009 :     case UNGT_EXPR:
   14108         1009 :       code = UNGT;
   14109         1009 :       break;
   14110         9942 :     case UNGE_EXPR:
   14111         9942 :       code = UNGE;
   14112         9942 :       break;
   14113          137 :     case UNEQ_EXPR:
   14114          137 :       code = UNEQ;
   14115          137 :       break;
   14116           88 :     case LTGT_EXPR:
   14117           88 :       code = LTGT;
   14118           88 :       break;
   14119              : 
   14120            0 :     default:
   14121            0 :       gcc_unreachable ();
   14122              :     }
   14123              : 
   14124              :   /* Put a constant second.  */
   14125       613561 :   if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
   14126       611591 :       || TREE_CODE (arg0) == FIXED_CST)
   14127              :     {
   14128         1970 :       std::swap (arg0, arg1);
   14129         1970 :       code = swap_condition (code);
   14130              :     }
   14131              : 
   14132              :   /* If this is an equality or inequality test of a single bit, we can
   14133              :      do this by shifting the bit being tested to the low-order bit and
   14134              :      masking the result with the constant 1.  If the condition was EQ,
   14135              :      we xor it with 1.  This does not require an scc insn and is faster
   14136              :      than an scc insn even if we have it.  */
   14137              : 
   14138       613561 :   if ((code == NE || code == EQ)
   14139       413598 :       && (integer_zerop (arg1)
   14140       259949 :           || integer_pow2p (arg1))
   14141              :       /* vector types are not handled here. */
   14142       186796 :       && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE
   14143       800317 :       && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
   14144              :     {
   14145       186756 :       tree narg0 = arg0;
   14146       186756 :       wide_int nz = tree_nonzero_bits (narg0);
   14147       186756 :       gimple *srcstmt = get_def_for_expr (narg0, BIT_AND_EXPR);
   14148              :       /* If the defining statement was (x & POW2), then use that instead of
   14149              :          the non-zero bits.  */
   14150       186756 :       if (srcstmt && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
   14151              :         {
   14152         5462 :           nz = wi::to_wide (gimple_assign_rhs2 (srcstmt));
   14153         5462 :           narg0 = gimple_assign_rhs1 (srcstmt);
   14154              :         }
   14155              : 
   14156       186756 :       if (wi::popcount (nz) == 1
   14157       186756 :           && (integer_zerop (arg1)
   14158       186756 :               || wi::to_wide (arg1) == nz))
   14159              :         {
   14160         9845 :           int bitnum = wi::exact_log2 (nz);
   14161         9845 :           enum tree_code tcode = EQ_EXPR;
   14162         9845 :           if ((code == NE) ^ !integer_zerop (arg1))
   14163         7104 :             tcode = NE_EXPR;
   14164              : 
   14165         9845 :           type = lang_hooks.types.type_for_mode (mode, unsignedp);
   14166         9845 :           return expand_single_bit_test (loc, tcode,
   14167              :                                          narg0,
   14168              :                                          bitnum, type, target, mode);
   14169              :         }
   14170       186756 :     }
   14171              : 
   14172              : 
   14173       603716 :   if (! get_subtarget (target)
   14174       603716 :       || GET_MODE (subtarget) != operand_mode)
   14175              :     subtarget = 0;
   14176              : 
   14177       603716 :   expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
   14178              : 
   14179              :   /* For boolean vectors with less than mode precision
   14180              :      make sure to fill padding with consistent values.  */
   14181           40 :   if (VECTOR_BOOLEAN_TYPE_P (type)
   14182           27 :       && SCALAR_INT_MODE_P (operand_mode)
   14183       603716 :       && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
   14184       603716 :       && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
   14185              :     {
   14186            0 :       gcc_assert (code == EQ || code == NE);
   14187            0 :       op0 = expand_binop (mode, and_optab, op0,
   14188            0 :                           GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
   14189              :                           NULL_RTX, true, OPTAB_WIDEN);
   14190            0 :       op1 = expand_binop (mode, and_optab, op1,
   14191              :                           GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
   14192              :                           NULL_RTX, true, OPTAB_WIDEN);
   14193              :     }
   14194              : 
   14195       603716 :   if (target == 0)
   14196       415464 :     target = gen_reg_rtx (mode);
   14197              : 
   14198              :   /* Try a cstore if possible.  */
   14199       603716 :   return emit_store_flag_force (target, code, op0, op1,
   14200              :                                 operand_mode, unsignedp,
   14201       603716 :                                 (TYPE_PRECISION (ops->type) == 1
   14202      1206760 :                                  && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
   14203              : }
   14204              : 
   14205              : /* Attempt to generate a casesi instruction.  Returns true if successful,
   14206              :    false otherwise (i.e. if there is no casesi instruction).
   14207              : 
   14208              :    DEFAULT_PROBABILITY is the probability of jumping to the default
   14209              :    label.  */
   14210              : bool
   14211         7094 : try_casesi (tree index_type, tree index_expr, tree minval, tree range,
   14212              :             rtx table_label, rtx default_label, rtx fallback_label,
   14213              :             profile_probability default_probability)
   14214              : {
   14215         7094 :   class expand_operand ops[5];
   14216         7094 :   scalar_int_mode index_mode = SImode;
   14217         7094 :   rtx op1, op2, index;
   14218              : 
   14219         7094 :   if (! targetm.have_casesi ())
   14220              :     return false;
   14221              : 
   14222              :   /* The index must be some form of integer.  Convert it to SImode.  */
   14223            0 :   scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
   14224            0 :   if (GET_MODE_BITSIZE (omode) > GET_MODE_BITSIZE (index_mode))
   14225              :     {
   14226            0 :       rtx rangertx = expand_normal (range);
   14227              : 
   14228              :       /* We must handle the endpoints in the original mode.  */
   14229            0 :       index_expr = build2 (MINUS_EXPR, index_type,
   14230              :                            index_expr, minval);
   14231            0 :       minval = integer_zero_node;
   14232            0 :       index = expand_normal (index_expr);
   14233            0 :       if (default_label)
   14234            0 :         emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
   14235              :                                  omode, 1, default_label,
   14236              :                                  default_probability);
   14237              :       /* Now we can safely truncate.  */
   14238            0 :       index = convert_to_mode (index_mode, index, 0);
   14239              :     }
   14240              :   else
   14241              :     {
   14242            0 :       if (omode != index_mode)
   14243              :         {
   14244            0 :           index_type = lang_hooks.types.type_for_mode (index_mode, 0);
   14245            0 :           index_expr = fold_convert (index_type, index_expr);
   14246              :         }
   14247              : 
   14248            0 :       index = expand_normal (index_expr);
   14249              :     }
   14250              : 
   14251            0 :   do_pending_stack_adjust ();
   14252              : 
   14253            0 :   op1 = expand_normal (minval);
   14254            0 :   op2 = expand_normal (range);
   14255              : 
   14256            0 :   create_input_operand (&ops[0], index, index_mode);
   14257            0 :   create_convert_operand_from_type (&ops[1], op1, TREE_TYPE (minval));
   14258            0 :   create_convert_operand_from_type (&ops[2], op2, TREE_TYPE (range));
   14259            0 :   create_fixed_operand (&ops[3], table_label);
   14260            0 :   create_fixed_operand (&ops[4], (default_label
   14261              :                                   ? default_label
   14262              :                                   : fallback_label));
   14263            0 :   expand_jump_insn (targetm.code_for_casesi, 5, ops);
   14264            0 :   return true;
   14265              : }
   14266              : 
   14267              : /* Attempt to generate a tablejump instruction; same concept.  */
   14268              : /* Subroutine of the next function.
   14269              : 
   14270              :    INDEX is the value being switched on, with the lowest value
   14271              :    in the table already subtracted.
   14272              :    MODE is its expected mode (needed if INDEX is constant).
   14273              :    RANGE is the length of the jump table.
   14274              :    TABLE_LABEL is a CODE_LABEL rtx for the table itself.
   14275              : 
   14276              :    DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
   14277              :    index value is out of range.
   14278              :    DEFAULT_PROBABILITY is the probability of jumping to
   14279              :    the default label.  */
   14280              : 
   14281              : static void
   14282         7094 : do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
   14283              :               rtx default_label, profile_probability default_probability)
   14284              : {
   14285         7094 :   rtx temp, vector;
   14286              : 
   14287         7094 :   if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
   14288         6000 :     cfun->cfg->max_jumptable_ents = INTVAL (range);
   14289              : 
   14290              :   /* Do an unsigned comparison (in the proper mode) between the index
   14291              :      expression and the value which represents the length of the range.
   14292              :      Since we just finished subtracting the lower bound of the range
   14293              :      from the index expression, this comparison allows us to simultaneously
   14294              :      check that the original index expression value is both greater than
   14295              :      or equal to the minimum value of the range and less than or equal to
   14296              :      the maximum value of the range.  */
   14297              : 
   14298         7094 :   if (default_label)
   14299         7048 :     emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
   14300              :                              default_label, default_probability);
   14301              : 
   14302              :   /* If index is in range, it must fit in Pmode.
   14303              :      Convert to Pmode so we can index with it.  */
   14304         8163 :   if (mode != Pmode)
   14305              :     {
   14306         6089 :       unsigned int width;
   14307              : 
   14308              :       /* We know the value of INDEX is between 0 and RANGE.  If we have a
   14309              :          sign-extended subreg, and RANGE does not have the sign bit set, then
   14310              :          we have a value that is valid for both sign and zero extension.  In
   14311              :          this case, we get better code if we sign extend.  */
   14312         6089 :       if (GET_CODE (index) == SUBREG
   14313            9 :           && SUBREG_PROMOTED_VAR_P (index)
   14314            0 :           && SUBREG_PROMOTED_SIGNED_P (index)
   14315            0 :           && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode)))
   14316              :               <= HOST_BITS_PER_WIDE_INT)
   14317         6089 :           && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
   14318            0 :         index = convert_to_mode (Pmode, index, 0);
   14319              :       else
   14320         6089 :         index = convert_to_mode (Pmode, index, 1);
   14321              :     }
   14322              : 
   14323              :   /* Don't let a MEM slip through, because then INDEX that comes
   14324              :      out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
   14325              :      and break_out_memory_refs will go to work on it and mess it up.  */
   14326              : #ifdef PIC_CASE_VECTOR_ADDRESS
   14327              :   if (flag_pic && !REG_P (index))
   14328              :     index = copy_to_mode_reg (Pmode, index);
   14329              : #endif
   14330              : 
   14331              :   /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
   14332              :      GET_MODE_SIZE, because this indicates how large insns are.  The other
   14333              :      uses should all be Pmode, because they are addresses.  This code
   14334              :      could fail if addresses and insns are not the same size.  */
   14335         8163 :   index = simplify_gen_binary (MULT, Pmode, index,
   14336        14188 :                                gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
   14337         7094 :                                              Pmode));
   14338         8163 :   index = simplify_gen_binary (PLUS, Pmode, index,
   14339         7094 :                                gen_rtx_LABEL_REF (Pmode, table_label));
   14340              : 
   14341              : #ifdef PIC_CASE_VECTOR_ADDRESS
   14342              :   if (flag_pic)
   14343              :     index = PIC_CASE_VECTOR_ADDRESS (index);
   14344              :   else
   14345              : #endif
   14346         8775 :     index = memory_address (CASE_VECTOR_MODE, index);
   14347         8775 :   temp = gen_reg_rtx (CASE_VECTOR_MODE);
   14348         8775 :   vector = gen_const_mem (CASE_VECTOR_MODE, index);
   14349         7094 :   convert_move (temp, vector, 0);
   14350              : 
   14351         7094 :   emit_jump_insn (targetm.gen_tablejump (temp, table_label));
   14352              : 
   14353              :   /* If we are generating PIC code or if the table is PC-relative, the
   14354              :      table and JUMP_INSN must be adjacent, so don't output a BARRIER.  */
   14355         7094 :   if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
   14356         5916 :     emit_barrier ();
   14357         7094 : }
   14358              : 
   14359              : bool
   14360         7094 : try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
   14361              :                rtx table_label, rtx default_label,
   14362              :                profile_probability default_probability)
   14363              : {
   14364         7094 :   rtx index;
   14365              : 
   14366         7094 :   if (! targetm.have_tablejump ())
   14367              :     return false;
   14368              : 
   14369         7094 :   index_expr = fold_build2 (MINUS_EXPR, index_type,
   14370              :                             fold_convert (index_type, index_expr),
   14371              :                             fold_convert (index_type, minval));
   14372         7094 :   index = expand_normal (index_expr);
   14373         7094 :   do_pending_stack_adjust ();
   14374              : 
   14375         7094 :   do_tablejump (index, TYPE_MODE (index_type),
   14376         7094 :                 convert_modes (TYPE_MODE (index_type),
   14377         7094 :                                TYPE_MODE (TREE_TYPE (range)),
   14378              :                                expand_normal (range),
   14379         7094 :                                TYPE_UNSIGNED (TREE_TYPE (range))),
   14380              :                 table_label, default_label, default_probability);
   14381         7094 :   return true;
   14382              : }
   14383              : 
   14384              : /* Return a CONST_VECTOR rtx representing vector mask for
   14385              :    a VECTOR_CST of booleans.  */
   14386              : static rtx
   14387          684 : const_vector_mask_from_tree (tree exp)
   14388              : {
   14389          684 :   machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   14390          684 :   machine_mode inner = GET_MODE_INNER (mode);
   14391              : 
   14392          684 :   rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
   14393          684 :                               VECTOR_CST_NELTS_PER_PATTERN (exp));
   14394          684 :   unsigned int count = builder.encoded_nelts ();
   14395         3680 :   for (unsigned int i = 0; i < count; ++i)
   14396              :     {
   14397         2996 :       tree elt = VECTOR_CST_ELT (exp, i);
   14398         2996 :       gcc_assert (TREE_CODE (elt) == INTEGER_CST);
   14399         2996 :       if (integer_zerop (elt))
   14400         1177 :         builder.quick_push (CONST0_RTX (inner));
   14401         1819 :       else if (integer_onep (elt)
   14402         1819 :                || integer_minus_onep (elt))
   14403         1819 :         builder.quick_push (CONSTM1_RTX (inner));
   14404              :       else
   14405            0 :         gcc_unreachable ();
   14406              :     }
   14407          684 :   return builder.build ();
   14408          684 : }
   14409              : 
   14410              : /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
   14411              : static rtx
   14412       571288 : const_vector_from_tree (tree exp)
   14413              : {
   14414       571288 :   machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   14415              : 
   14416       571288 :   if (initializer_zerop (exp))
   14417       170051 :     return CONST0_RTX (mode);
   14418              : 
   14419       401237 :   if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
   14420          684 :     return const_vector_mask_from_tree (exp);
   14421              : 
   14422       400553 :   machine_mode inner = GET_MODE_INNER (mode);
   14423              : 
   14424       400553 :   rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
   14425       400553 :                               VECTOR_CST_NELTS_PER_PATTERN (exp));
   14426       400553 :   unsigned int count = builder.encoded_nelts ();
   14427      1291489 :   for (unsigned int i = 0; i < count; ++i)
   14428              :     {
   14429       890936 :       tree elt = VECTOR_CST_ELT (exp, i);
   14430       890936 :       if (TREE_CODE (elt) == REAL_CST)
   14431       136281 :         builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt),
   14432              :                                                           inner));
   14433       754655 :       else if (TREE_CODE (elt) == FIXED_CST)
   14434            0 :         builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
   14435              :                                                           inner));
   14436              :       else
   14437       754655 :         builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt),
   14438              :                                                   inner));
   14439              :     }
   14440       400553 :   return builder.build ();
   14441       400553 : }
   14442              : 
   14443              : /* Build a decl for a personality function given a language prefix.  */
   14444              : 
   14445              : tree
   14446        33258 : build_personality_function (const char *lang)
   14447              : {
   14448        33258 :   const char *unwind_and_version;
   14449        33258 :   tree decl, type;
   14450        33258 :   char *name;
   14451              : 
   14452        33258 :   switch (targetm_common.except_unwind_info (&global_options))
   14453              :     {
   14454              :     case UI_NONE:
   14455              :       return NULL;
   14456              :     case UI_SJLJ:
   14457              :       unwind_and_version = "_sj0";
   14458              :       break;
   14459        33258 :     case UI_DWARF2:
   14460        33258 :     case UI_TARGET:
   14461        33258 :       unwind_and_version = "_v0";
   14462        33258 :       break;
   14463            0 :     case UI_SEH:
   14464            0 :       unwind_and_version = "_seh0";
   14465            0 :       break;
   14466            0 :     default:
   14467            0 :       gcc_unreachable ();
   14468              :     }
   14469              : 
   14470        33258 :   name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
   14471              : 
   14472        33258 :   type = build_function_type_list (unsigned_type_node,
   14473              :                                    integer_type_node, integer_type_node,
   14474              :                                    long_long_unsigned_type_node,
   14475              :                                    ptr_type_node, ptr_type_node, NULL_TREE);
   14476        33258 :   decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
   14477              :                      get_identifier (name), type);
   14478        33258 :   DECL_ARTIFICIAL (decl) = 1;
   14479        33258 :   DECL_EXTERNAL (decl) = 1;
   14480        33258 :   TREE_PUBLIC (decl) = 1;
   14481              : 
   14482              :   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
   14483              :      are the flags assigned by targetm.encode_section_info.  */
   14484        33258 :   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
   14485              : 
   14486        33258 :   return decl;
   14487              : }
   14488              : 
   14489              : /* Extracts the personality function of DECL and returns the corresponding
   14490              :    libfunc.  */
   14491              : 
   14492              : rtx
   14493      1661973 : get_personality_function (tree decl)
   14494              : {
   14495      1661973 :   tree personality = DECL_FUNCTION_PERSONALITY (decl);
   14496      1661973 :   enum eh_personality_kind pk;
   14497              : 
   14498      1661973 :   pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
   14499      1661973 :   if (pk == eh_personality_none)
   14500              :     return NULL;
   14501              : 
   14502       158394 :   if (!personality
   14503       158394 :       && pk == eh_personality_any)
   14504        72384 :     personality = lang_hooks.eh_personality ();
   14505              : 
   14506       158394 :   if (pk == eh_personality_lang)
   14507        86010 :     gcc_assert (personality != NULL_TREE);
   14508              : 
   14509       158394 :   return XEXP (DECL_RTL (personality), 0);
   14510              : }
   14511              : 
   14512              : /* Returns a tree for the size of EXP in bytes.  */
   14513              : 
   14514              : static tree
   14515     14919295 : tree_expr_size (const_tree exp)
   14516              : {
   14517     14919295 :   if (DECL_P (exp)
   14518     14919295 :       && DECL_SIZE_UNIT (exp) != 0)
   14519      1949842 :     return DECL_SIZE_UNIT (exp);
   14520              :   else
   14521     12969453 :     return size_in_bytes (TREE_TYPE (exp));
   14522              : }
   14523              : 
   14524              : /* Return an rtx for the size in bytes of the value of EXP.  */
   14525              : 
   14526              : rtx
   14527     14724744 : expr_size (tree exp)
   14528              : {
   14529     14724744 :   tree size;
   14530              : 
   14531     14724744 :   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
   14532          773 :     size = TREE_OPERAND (exp, 1);
   14533              :   else
   14534              :     {
   14535     14723971 :       size = tree_expr_size (exp);
   14536     14723971 :       gcc_assert (size);
   14537     14723971 :       gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
   14538              :     }
   14539              : 
   14540     14724744 :   return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
   14541              : }
   14542              : 
   14543              : /* Return a wide integer for the size in bytes of the value of EXP, or -1
   14544              :    if the size can vary or is larger than an integer.  */
   14545              : 
   14546              : HOST_WIDE_INT
   14547       195324 : int_expr_size (const_tree exp)
   14548              : {
   14549       195324 :   tree size;
   14550              : 
   14551       195324 :   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
   14552            0 :     size = TREE_OPERAND (exp, 1);
   14553              :   else
   14554              :     {
   14555       195324 :       size = tree_expr_size (exp);
   14556       195324 :       gcc_assert (size);
   14557              :     }
   14558              : 
   14559       195324 :   if (size == 0 || !tree_fits_shwi_p (size))
   14560              :     return -1;
   14561              : 
   14562       195324 :   return tree_to_shwi (size);
   14563              : }
   14564              : 
   14565              : /* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
   14566              :    in GF (2^N).
   14567              :    Author: Richard Sandiford <richard.sandiford@arm.com>  */
   14568              : 
   14569              : unsigned HOST_WIDE_INT
   14570            0 : gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
   14571              :                              unsigned short n)
   14572              : {
   14573              :   /* The result has degree N, so needs N + 1 bits.  */
   14574            0 :   gcc_assert (n < 64);
   14575              : 
   14576              :   /* Perform a division step for the x^2N coefficient.  At this point the
   14577              :      quotient and remainder have N implicit trailing zeros.  */
   14578              :   unsigned HOST_WIDE_INT quotient = 1;
   14579              :   unsigned HOST_WIDE_INT remainder = polynomial;
   14580              : 
   14581              :   /* Process the coefficients for x^(2N-1) down to x^N, with each step
   14582              :      reducing the number of implicit trailing zeros by one.  */
   14583            0 :   for (unsigned int i = 0; i < n; ++i)
   14584              :     {
   14585            0 :       bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
   14586            0 :       quotient = (quotient << 1) | coeff;
   14587            0 :       remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
   14588              :     }
   14589            0 :   return quotient;
   14590              : }
   14591              : 
   14592              : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
   14593              :    POLYNOM is the polynomial used to calculate the CRC table's elements.
   14594              :    CRC_BITS is the size of CRC, may be 8, 16, ... . */
   14595              : 
   14596              : static rtx
   14597          144 : assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   14598              : {
   14599          144 :   unsigned table_el_n = 0x100;
   14600          144 :   tree ar = build_array_type (make_unsigned_type (crc_bits),
   14601          144 :                               build_index_type (size_int (table_el_n - 1)));
   14602              : 
   14603              :   /* Initialize the table.  */
   14604          144 :   vec<tree, va_gc> *initial_values;
   14605          144 :   vec_alloc (initial_values, table_el_n);
   14606        37152 :   for (size_t i = 0; i < table_el_n; ++i)
   14607              :     {
   14608        36864 :       unsigned HOST_WIDE_INT crc = calculate_crc (0, i, polynom, crc_bits, 8);
   14609        36864 :       tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
   14610        36864 :       vec_safe_push (initial_values, element);
   14611              :     }
   14612          144 :   tree ctor = build_constructor_from_vec (ar, initial_values);
   14613          144 :   rtx mem = output_constant_def (ctor, 1);
   14614          144 :   gcc_assert (MEM_P (mem));
   14615          144 :   if (dump_file && (dump_flags & TDF_DETAILS))
   14616              :     {
   14617           16 :       fprintf (dump_file,
   14618              :                ";; emitting crc table crc_%u_polynomial_"
   14619              :                HOST_WIDE_INT_PRINT_HEX " ",
   14620              :                crc_bits, polynom);
   14621           16 :       print_rtl_single (dump_file, XEXP (mem, 0));
   14622           16 :       fprintf (dump_file, "\n");
   14623              :     }
   14624              : 
   14625          144 :   return XEXP (mem, 0);
   14626              : }
   14627              : 
   14628              : /* Generate CRC lookup table by calculating CRC for all possible
   14629              :    8-bit data values.  The table is stored with a specific name in the read-only
   14630              :    static data section.
   14631              :    POLYNOM is the polynomial used to calculate the CRC table's elements.
   14632              :    CRC_BITS is the size of CRC, may be 8, 16, ... .  */
   14633              : 
   14634              : static rtx
   14635          144 : generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   14636              : {
   14637          144 :   gcc_assert (crc_bits <= 64);
   14638              : 
   14639          144 :   return assemble_crc_table (polynom, crc_bits);
   14640              : }
   14641              : 
   14642              : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
   14643              :    POLYNOM is the polynomial used to calculate the CRC table's elements.
   14644              :    CRC_BITS is the size of CRC, may be 8, 16, ... . */
   14645              : 
   14646              : static rtx
   14647          136 : assemble_reversed_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   14648              : {
   14649          136 :   unsigned table_el_n = 0x100;
   14650          136 :   tree ar = build_array_type (make_unsigned_type (crc_bits),
   14651          136 :                               build_index_type (size_int (table_el_n - 1)));
   14652              : 
   14653              :   /* Initialize the table.  */
   14654          136 :   vec<tree, va_gc> *initial_values;
   14655          136 :   vec_alloc (initial_values, table_el_n);
   14656        35088 :   for (size_t i = 0; i < table_el_n; ++i)
   14657              :     {
   14658        34816 :       unsigned HOST_WIDE_INT crc = calculate_reversed_crc (0, i, polynom,
   14659        34816 :                                                            crc_bits, 8);
   14660        34816 :       tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
   14661        34816 :       vec_safe_push (initial_values, element);
   14662              :     }
   14663          136 :   tree ctor = build_constructor_from_vec (ar, initial_values);
   14664          136 :   rtx mem = output_constant_def (ctor, 1);
   14665          136 :   gcc_assert (MEM_P (mem));
   14666          136 :   if (dump_file && (dump_flags & TDF_DETAILS))
   14667              :     {
   14668           16 :       fprintf (dump_file,
   14669              :                ";; emitting reversed crc table crc_%u_polynomial_"
   14670              :                HOST_WIDE_INT_PRINT_HEX " ",
   14671              :                crc_bits, polynom);
   14672           16 :       print_rtl_single (dump_file, XEXP (mem, 0));
   14673           16 :       fprintf (dump_file, "\n");
   14674              :     }
   14675              : 
   14676          136 :   return XEXP (mem, 0);
   14677              : }
   14678              : 
   14679              : /* Generate reversed CRC table for the given POLYNOM and CRC_BITS.  */
   14680              : 
   14681              : static rtx
   14682          136 : generate_reversed_crc_table (unsigned HOST_WIDE_INT polynom,
   14683              :                              unsigned short crc_bits)
   14684              : {
   14685          136 :   gcc_assert (crc_bits <= 64);
   14686              : 
   14687          136 :   return assemble_reversed_crc_table (polynom, crc_bits);
   14688              : }
   14689              : 
   14690              : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
   14691              :    POLYNOMIAL (without leading 1).
   14692              : 
   14693              :    First, using POLYNOMIAL's value generates CRC table of 256 elements,
   14694              :    then generates the assembly for the following code,
   14695              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64, depending on CRC:
   14696              : 
   14697              :      for (int i = 0; i < data_bit_size / 8; i++)
   14698              :        crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
   14699              :                                     ^ (data >> (data_bit_size - (i + 1) * 8)
   14700              :                                     & 0xFF))];
   14701              : 
   14702              :    So to take values from the table, we need 8-bit data.
   14703              :    If input data size is not 8, then first we extract upper 8 bits,
   14704              :    then the other 8 bits, and so on.  */
   14705              : 
   14706              : static void
   14707          144 : calculate_table_based_CRC (rtx *crc, const rtx &input_data,
   14708              :                            const rtx &polynomial,
   14709              :                            machine_mode data_mode)
   14710              : {
   14711          144 :   machine_mode mode = GET_MODE (*crc);
   14712          144 :   unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
   14713          144 :   unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
   14714          144 :   rtx tab = generate_crc_table (UINTVAL (polynomial), crc_bit_size);
   14715              : 
   14716          586 :   for (unsigned short i = 0; i < data_size; i++)
   14717              :     {
   14718              :       /* crc >> (crc_bit_size - 8).  */
   14719          298 :       *crc = force_reg (mode, *crc);
   14720          298 :       rtx op1 = expand_shift (RSHIFT_EXPR, mode, *crc, crc_bit_size - 8,
   14721              :                               NULL_RTX, 1);
   14722              : 
   14723              :       /* data >> (8 * (GET_MODE_SIZE (data_mode).to_constant () - i - 1)).  */
   14724          298 :       unsigned range_8 = 8 * (data_size - i - 1);
   14725              :       /* CRC's mode is always at least as wide as INPUT_DATA.  Convert
   14726              :          INPUT_DATA into CRC's mode.  */
   14727          298 :       rtx data = gen_reg_rtx (mode);
   14728          298 :       convert_move (data, input_data, 1);
   14729          298 :       data = expand_shift (RSHIFT_EXPR, mode, data, range_8, NULL_RTX, 1);
   14730              : 
   14731              :       /* data >> (8 * (GET_MODE_SIZE (mode)
   14732              :                                         .to_constant () - i - 1)) & 0xFF.  */
   14733          298 :       rtx data_final = expand_and (mode, data,
   14734              :                                    gen_int_mode (255, mode), NULL_RTX);
   14735              : 
   14736              :       /* (crc >> (crc_bit_size - 8)) ^ data_8bit.  */
   14737          298 :       rtx in = expand_binop (mode, xor_optab, op1, data_final,
   14738              :                              NULL_RTX, 1, OPTAB_WIDEN);
   14739              : 
   14740              :       /* ((crc >> (crc_bit_size - 8)) ^ data_8bit) & 0xFF.  */
   14741          298 :       rtx index = expand_and (mode, in, gen_int_mode (255, mode),
   14742              :                               NULL_RTX);
   14743          596 :       int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
   14744          298 :       index = expand_shift (LSHIFT_EXPR, mode, index,
   14745          298 :                             log_crc_size, NULL_RTX, 0);
   14746              : 
   14747          303 :       rtx addr = gen_reg_rtx (Pmode);
   14748          298 :       convert_move (addr, index, 1);
   14749          303 :       addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
   14750              :                             0, OPTAB_DIRECT);
   14751              : 
   14752              :       /* crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit]  */
   14753          298 :       rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
   14754              : 
   14755              :       /* (crc << 8) if CRC is larger than 8, otherwise crc = 0.  */
   14756          298 :       rtx high = NULL_RTX;
   14757          298 :       if (crc_bit_size != 8)
   14758          269 :         high = expand_shift (LSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 0);
   14759              :       else
   14760           29 :         high = gen_int_mode (0, mode);
   14761              : 
   14762              :       /* crc = (crc << 8)
   14763              :                ^ crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit];  */
   14764          298 :       *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
   14765              :                            OPTAB_WIDEN);
   14766              :     }
   14767          144 : }
   14768              : 
   14769              : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA
   14770              :    and the POLYNOMIAL (without leading 1).
   14771              : 
   14772              :    This function generates code for reversed (bit-reflected) CRC calculation
   14773              :    using a pre-computed lookup table.  Unlike the standard CRC calculation,
   14774              :    this processes data from LSB to MSB, eliminating the need for explicit
   14775              :    bit reflection before and after the CRC computation.  */
   14776              : 
   14777              : static void
   14778          136 : calculate_table_based_reversed_CRC (rtx *crc, const rtx &input_data,
   14779              :                                     const rtx &polynomial,
   14780              :                                     machine_mode data_mode)
   14781              : {
   14782          136 :   machine_mode mode = GET_MODE (*crc);
   14783          136 :   unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
   14784          136 :   unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
   14785          136 :   rtx tab = generate_reversed_crc_table (UINTVAL (polynomial), crc_bit_size);
   14786              : 
   14787              :   /* CRC's mode is always at least as wide as INPUT_DATA.  Convert
   14788              :      INPUT_DATA into CRC's mode once outside the loop since INPUT_DATA
   14789              :      is loop-invariant.  */
   14790          136 :   rtx data_in_crc_mode = gen_reg_rtx (mode);
   14791          136 :   convert_move (data_in_crc_mode, input_data, 1);
   14792              : 
   14793          490 :   for (unsigned short i = 0; i < data_size; i++)
   14794              :     {
   14795          218 :       *crc = force_reg (mode, *crc);
   14796              : 
   14797              :       /* data >> (8 * i).  */
   14798          218 :       unsigned range_8 = 8 * i;
   14799          218 :       rtx data = expand_shift (RSHIFT_EXPR, mode, data_in_crc_mode,
   14800          218 :                                range_8, NULL_RTX, 1);
   14801              : 
   14802              :       /* crc ^ (data >> (8 * i)).  */
   14803          218 :       rtx in = expand_binop (mode, xor_optab, *crc, data,
   14804              :                              NULL_RTX, 1, OPTAB_WIDEN);
   14805              : 
   14806              :       /* (crc ^ data) & 0xFF.  */
   14807          218 :       rtx index = expand_and (mode, in, gen_int_mode (255, mode),
   14808              :                               NULL_RTX);
   14809          436 :       int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
   14810          218 :       index = expand_shift (LSHIFT_EXPR, mode, index,
   14811          218 :                             log_crc_size, NULL_RTX, 0);
   14812              : 
   14813          231 :       rtx addr = gen_reg_rtx (Pmode);
   14814          218 :       convert_move (addr, index, 1);
   14815          231 :       addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
   14816              :                             0, OPTAB_DIRECT);
   14817              : 
   14818              :       /* crc_table[(crc ^ data) & 0xFF].  */
   14819          218 :       rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
   14820              : 
   14821              :       /* (crc >> 8) if CRC is larger than 8, otherwise 0.  */
   14822          218 :       rtx high = NULL_RTX;
   14823          218 :       if (crc_bit_size != 8)
   14824          209 :         high = expand_shift (RSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 1);
   14825              :       else
   14826            9 :         high = gen_int_mode (0, mode);
   14827              : 
   14828              :       /* crc = (crc >> 8) ^ crc_table[(crc ^ data) & 0xFF].  */
   14829          218 :       *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
   14830              :                            OPTAB_WIDEN);
   14831              :     }
   14832          136 : }
   14833              : 
   14834              : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
   14835              :    POLYNOMIAL (without leading 1).
   14836              : 
   14837              :    CRC is OP1, data is OP2 and the polynomial is OP3.
   14838              :    This must generate a CRC table and an assembly for the following code,
   14839              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
   14840              :    uint_crc_bit_size_t
   14841              :    crc_crc_bit_size (uint_crc_bit_size_t crc_init,
   14842              :                      uint_data_bit_size_t data, size_t size)
   14843              :    {
   14844              :      uint_crc_bit_size_t crc = crc_init;
   14845              :      for (int i = 0; i < data_bit_size / 8; i++)
   14846              :        crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
   14847              :                                     ^ (data >> (data_bit_size - (i + 1) * 8)
   14848              :                                     & 0xFF))];
   14849              :      return crc;
   14850              :    }  */
   14851              : 
   14852              : void
   14853          144 : expand_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
   14854              :                         machine_mode data_mode)
   14855              : {
   14856          144 :   gcc_assert (!CONST_INT_P (op0));
   14857          144 :   gcc_assert (CONST_INT_P (op3));
   14858          144 :   machine_mode crc_mode = GET_MODE (op0);
   14859          144 :   rtx crc = gen_reg_rtx (crc_mode);
   14860          144 :   convert_move (crc, op1, 0);
   14861          144 :   calculate_table_based_CRC (&crc, op2, op3, data_mode);
   14862          144 :   convert_move (op0, crc, 0);
   14863          144 : }
   14864              : 
   14865              : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA and
   14866              :    the POLYNOMIAL (without leading 1).
   14867              : 
   14868              :    CRC is OP1, data is OP2 and the polynomial is OP3.
   14869              :    This generates a reversed CRC table and assembly for the following code,
   14870              :    where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
   14871              :    uint_crc_bit_size_t
   14872              :    crc_crc_bit_size (uint_crc_bit_size_t crc_init,
   14873              :                      uint_data_bit_size_t data)
   14874              :    {
   14875              :      uint_crc_bit_size_t crc = crc_init;
   14876              :      for (int i = 0; i < data_bit_size / 8; i++)
   14877              :        crc = (crc >> 8) ^ crc_table[(crc ^ (data >> (i * 8))) & 0xFF];
   14878              :      return crc;
   14879              :    }
   14880              : 
   14881              :    This approach uses a pre-computed reversed polynomial table, eliminating
   14882              :    the need for explicit bit reflection before and after the CRC computation.  */
   14883              : 
   14884              : void
   14885          136 : expand_reversed_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
   14886              :                                  machine_mode data_mode)
   14887              : {
   14888          136 :   gcc_assert (!CONST_INT_P (op0));
   14889          136 :   gcc_assert (CONST_INT_P (op3));
   14890          136 :   machine_mode crc_mode = GET_MODE (op0);
   14891          136 :   rtx crc = gen_reg_rtx (crc_mode);
   14892          136 :   convert_move (crc, op1, 0);
   14893          136 :   calculate_table_based_reversed_CRC (&crc, op2, op3, data_mode);
   14894          136 :   convert_move (op0, crc, 0);
   14895          136 : }
        

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.