LCOV - code coverage report
Current view: top level - gcc - gimple-fold.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 3462 3675 94.2 %
Date: 2020-04-04 11:58:09 Functions: 107 109 98.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Statement simplification on GIMPLE.
       2                 :            :    Copyright (C) 2010-2020 Free Software Foundation, Inc.
       3                 :            :    Split out from tree-ssa-ccp.c.
       4                 :            : 
       5                 :            : This file is part of GCC.
       6                 :            : 
       7                 :            : GCC is free software; you can redistribute it and/or modify it
       8                 :            : under the terms of the GNU General Public License as published by the
       9                 :            : Free Software Foundation; either version 3, or (at your option) any
      10                 :            : later version.
      11                 :            : 
      12                 :            : GCC is distributed in the hope that it will be useful, but WITHOUT
      13                 :            : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :            : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :            : for more details.
      16                 :            : 
      17                 :            : You should have received a copy of the GNU General Public License
      18                 :            : along with GCC; see the file COPYING3.  If not see
      19                 :            : <http://www.gnu.org/licenses/>.  */
      20                 :            : 
      21                 :            : #include "config.h"
      22                 :            : #include "system.h"
      23                 :            : #include "coretypes.h"
      24                 :            : #include "backend.h"
      25                 :            : #include "target.h"
      26                 :            : #include "rtl.h"
      27                 :            : #include "tree.h"
      28                 :            : #include "gimple.h"
      29                 :            : #include "predict.h"
      30                 :            : #include "ssa.h"
      31                 :            : #include "cgraph.h"
      32                 :            : #include "gimple-pretty-print.h"
      33                 :            : #include "gimple-ssa-warn-restrict.h"
      34                 :            : #include "fold-const.h"
      35                 :            : #include "stmt.h"
      36                 :            : #include "expr.h"
      37                 :            : #include "stor-layout.h"
      38                 :            : #include "dumpfile.h"
      39                 :            : #include "gimple-fold.h"
      40                 :            : #include "gimplify.h"
      41                 :            : #include "gimple-iterator.h"
      42                 :            : #include "tree-into-ssa.h"
      43                 :            : #include "tree-dfa.h"
      44                 :            : #include "tree-object-size.h"
      45                 :            : #include "tree-ssa.h"
      46                 :            : #include "tree-ssa-propagate.h"
      47                 :            : #include "ipa-utils.h"
      48                 :            : #include "tree-ssa-address.h"
      49                 :            : #include "langhooks.h"
      50                 :            : #include "gimplify-me.h"
      51                 :            : #include "dbgcnt.h"
      52                 :            : #include "builtins.h"
      53                 :            : #include "tree-eh.h"
      54                 :            : #include "gimple-match.h"
      55                 :            : #include "gomp-constants.h"
      56                 :            : #include "optabs-query.h"
      57                 :            : #include "omp-general.h"
      58                 :            : #include "tree-cfg.h"
      59                 :            : #include "fold-const-call.h"
      60                 :            : #include "stringpool.h"
      61                 :            : #include "attribs.h"
      62                 :            : #include "asan.h"
      63                 :            : #include "diagnostic-core.h"
      64                 :            : #include "intl.h"
      65                 :            : #include "calls.h"
      66                 :            : #include "tree-vector-builder.h"
      67                 :            : #include "tree-ssa-strlen.h"
      68                 :            : #include "varasm.h"
      69                 :            : 
      70                 :            : enum strlen_range_kind {
      71                 :            :   /* Compute the exact constant string length.  */
      72                 :            :   SRK_STRLEN,
      73                 :            :   /* Compute the maximum constant string length.  */
      74                 :            :   SRK_STRLENMAX,
      75                 :            :   /* Compute a range of string lengths bounded by object sizes.  When
      76                 :            :      the length of a string cannot be determined, consider as the upper
      77                 :            :      bound the size of the enclosing object the string may be a member
      78                 :            :      or element of.  Also determine the size of the largest character
      79                 :            :      array the string may refer to.  */
      80                 :            :   SRK_LENRANGE,
      81                 :            :   /* Determine the integer value of the argument (not string length).  */
      82                 :            :   SRK_INT_VALUE
      83                 :            : };
      84                 :            : 
      85                 :            : static bool
      86                 :            : get_range_strlen (tree, bitmap *, strlen_range_kind, c_strlen_data *, unsigned);
      87                 :            : 
      88                 :            : /* Return true when DECL can be referenced from current unit.
      89                 :            :    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
      90                 :            :    We can get declarations that are not possible to reference for various
      91                 :            :    reasons:
      92                 :            : 
      93                 :            :      1) When analyzing C++ virtual tables.
      94                 :            :         C++ virtual tables do have known constructors even
      95                 :            :         when they are keyed to other compilation unit.
      96                 :            :         Those tables can contain pointers to methods and vars
      97                 :            :         in other units.  Those methods have both STATIC and EXTERNAL
      98                 :            :         set.
      99                 :            :      2) In WHOPR mode devirtualization might lead to reference
     100                 :            :         to method that was partitioned elsehwere.
     101                 :            :         In this case we have static VAR_DECL or FUNCTION_DECL
     102                 :            :         that has no corresponding callgraph/varpool node
     103                 :            :         declaring the body.  
     104                 :            :      3) COMDAT functions referred by external vtables that
     105                 :            :         we devirtualize only during final compilation stage.
     106                 :            :         At this time we already decided that we will not output
     107                 :            :         the function body and thus we can't reference the symbol
     108                 :            :         directly.  */
     109                 :            : 
     110                 :            : static bool
     111                 :    3752720 : can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
     112                 :            : {
     113                 :    3752720 :   varpool_node *vnode;
     114                 :    3752720 :   struct cgraph_node *node;
     115                 :    3752720 :   symtab_node *snode;
     116                 :            : 
     117                 :    3752720 :   if (DECL_ABSTRACT_P (decl))
     118                 :            :     return false;
     119                 :            : 
     120                 :            :   /* We are concerned only about static/external vars and functions.  */
     121                 :    1326130 :   if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
     122                 :    4846880 :       || !VAR_OR_FUNCTION_DECL_P (decl))
     123                 :            :     return true;
     124                 :            : 
     125                 :            :   /* Static objects can be referred only if they are defined and not optimized
     126                 :            :      out yet.  */
     127                 :    3520750 :   if (!TREE_PUBLIC (decl))
     128                 :            :     {
     129                 :     930057 :       if (DECL_EXTERNAL (decl))
     130                 :            :         return false;
     131                 :            :       /* Before we start optimizing unreachable code we can be sure all
     132                 :            :          static objects are defined.  */
     133                 :     930001 :       if (symtab->function_flags_ready)
     134                 :            :         return true;
     135                 :     896865 :       snode = symtab_node::get (decl);
     136                 :     896865 :       if (!snode || !snode->definition)
     137                 :            :         return false;
     138                 :     896824 :       node = dyn_cast <cgraph_node *> (snode);
     139                 :     896824 :       return !node || !node->inlined_to;
     140                 :            :     }
     141                 :            : 
     142                 :            :   /* We will later output the initializer, so we can refer to it.
     143                 :            :      So we are concerned only when DECL comes from initializer of
     144                 :            :      external var or var that has been optimized out.  */
     145                 :    2590700 :   if (!from_decl
     146                 :     325299 :       || !VAR_P (from_decl)
     147                 :     325151 :       || (!DECL_EXTERNAL (from_decl)
     148                 :     139903 :           && (vnode = varpool_node::get (from_decl)) != NULL
     149                 :     105633 :           && vnode->definition)
     150                 :    2810240 :       || (flag_ltrans
     151                 :          2 :           && (vnode = varpool_node::get (from_decl)) != NULL
     152                 :          2 :           && vnode->in_other_partition))
     153                 :            :     return true;
     154                 :            :   /* We are folding reference from external vtable.  The vtable may reffer
     155                 :            :      to a symbol keyed to other compilation unit.  The other compilation
     156                 :            :      unit may be in separate DSO and the symbol may be hidden.  */
     157                 :     219541 :   if (DECL_VISIBILITY_SPECIFIED (decl)
     158                 :     211474 :       && DECL_EXTERNAL (decl)
     159                 :     175398 :       && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT
     160                 :     327611 :       && (!(snode = symtab_node::get (decl)) || !snode->in_other_partition))
     161                 :            :     return false;
     162                 :            :   /* When function is public, we always can introduce new reference.
     163                 :            :      Exception are the COMDAT functions where introducing a direct
     164                 :            :      reference imply need to include function body in the curren tunit.  */
     165                 :     111471 :   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
     166                 :            :     return true;
     167                 :            :   /* We have COMDAT.  We are going to check if we still have definition
     168                 :            :      or if the definition is going to be output in other partition.
     169                 :            :      Bypass this when gimplifying; all needed functions will be produced.
     170                 :            : 
     171                 :            :      As observed in PR20991 for already optimized out comdat virtual functions
     172                 :            :      it may be tempting to not necessarily give up because the copy will be
     173                 :            :      output elsewhere when corresponding vtable is output.  
     174                 :            :      This is however not possible - ABI specify that COMDATs are output in
     175                 :            :      units where they are used and when the other unit was compiled with LTO
     176                 :            :      it is possible that vtable was kept public while the function itself
     177                 :            :      was privatized. */
     178                 :      48813 :   if (!symtab->function_flags_ready)
     179                 :            :     return true;
     180                 :            : 
     181                 :      46173 :   snode = symtab_node::get (decl);
     182                 :      46173 :   if (!snode
     183                 :      46173 :       || ((!snode->definition || DECL_EXTERNAL (decl))
     184                 :       1858 :           && (!snode->in_other_partition
     185                 :          0 :               || (!snode->forced_by_abi && !snode->force_output))))
     186                 :            :     return false;
     187                 :      30922 :   node = dyn_cast <cgraph_node *> (snode);
     188                 :      30922 :   return !node || !node->inlined_to;
     189                 :            : }
     190                 :            : 
     191                 :            : /* Create a temporary for TYPE for a statement STMT.  If the current function
     192                 :            :    is in SSA form, a SSA name is created.  Otherwise a temporary register
     193                 :            :    is made.  */
     194                 :            : 
     195                 :            : tree
     196                 :     778266 : create_tmp_reg_or_ssa_name (tree type, gimple *stmt)
     197                 :            : {
     198                 :     778266 :   if (gimple_in_ssa_p (cfun))
     199                 :     769372 :     return make_ssa_name (type, stmt);
     200                 :            :   else
     201                 :       8894 :     return create_tmp_reg (type);
     202                 :            : }
     203                 :            : 
     204                 :            : /* CVAL is value taken from DECL_INITIAL of variable.  Try to transform it into
     205                 :            :    acceptable form for is_gimple_min_invariant.
     206                 :            :    FROM_DECL (if non-NULL) specify variable whose constructor contains CVAL.  */
     207                 :            : 
     208                 :            : tree
     209                 :   12563900 : canonicalize_constructor_val (tree cval, tree from_decl)
     210                 :            : {
     211                 :   12563900 :   if (CONSTANT_CLASS_P (cval))
     212                 :            :     return cval;
     213                 :            : 
     214                 :    7939760 :   tree orig_cval = cval;
     215                 :    7939760 :   STRIP_NOPS (cval);
     216                 :    7939760 :   if (TREE_CODE (cval) == POINTER_PLUS_EXPR
     217                 :    7939760 :       && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
     218                 :            :     {
     219                 :      65195 :       tree ptr = TREE_OPERAND (cval, 0);
     220                 :      65195 :       if (is_gimple_min_invariant (ptr))
     221                 :     195276 :         cval = build1_loc (EXPR_LOCATION (cval),
     222                 :      65092 :                            ADDR_EXPR, TREE_TYPE (ptr),
     223                 :     130184 :                            fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),
     224                 :            :                                         ptr,
     225                 :            :                                         fold_convert (ptr_type_node,
     226                 :            :                                                       TREE_OPERAND (cval, 1))));
     227                 :            :     }
     228                 :    7939760 :   if (TREE_CODE (cval) == ADDR_EXPR)
     229                 :            :     {
     230                 :    4312700 :       tree base = NULL_TREE;
     231                 :    4312700 :       if (TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
     232                 :            :         {
     233                 :        173 :           base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
     234                 :        173 :           if (base)
     235                 :        173 :             TREE_OPERAND (cval, 0) = base;
     236                 :            :         }
     237                 :            :       else
     238                 :    4312530 :         base = get_base_address (TREE_OPERAND (cval, 0));
     239                 :    4312700 :       if (!base)
     240                 :            :         return NULL_TREE;
     241                 :            : 
     242                 :    4312700 :       if (VAR_OR_FUNCTION_DECL_P (base)
     243                 :    4312700 :           && !can_refer_decl_in_current_unit_p (base, from_decl))
     244                 :            :         return NULL_TREE;
     245                 :    4204270 :       if (TREE_TYPE (base) == error_mark_node)
     246                 :            :         return NULL_TREE;
     247                 :    4204270 :       if (VAR_P (base))
     248                 :    2284080 :         TREE_ADDRESSABLE (base) = 1;
     249                 :    1920190 :       else if (TREE_CODE (base) == FUNCTION_DECL)
     250                 :            :         {
     251                 :            :           /* Make sure we create a cgraph node for functions we'll reference.
     252                 :            :              They can be non-existent if the reference comes from an entry
     253                 :            :              of an external vtable for example.  */
     254                 :    1166880 :           cgraph_node::get_create (base);
     255                 :            :         }
     256                 :            :       /* Fixup types in global initializers.  */
     257                 :    4204270 :       if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
     258                 :      18551 :         cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
     259                 :            : 
     260                 :    4204270 :       if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
     261                 :     128258 :         cval = fold_convert (TREE_TYPE (orig_cval), cval);
     262                 :    4204270 :       return cval;
     263                 :            :     }
     264                 :            :   /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0.  */
     265                 :    3627060 :   if (TREE_CODE (cval) == INTEGER_CST)
     266                 :            :     {
     267                 :      56394 :       if (TREE_OVERFLOW_P (cval))
     268                 :          0 :         cval = drop_tree_overflow (cval);
     269                 :      56394 :       if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
     270                 :      56394 :         cval = fold_convert (TREE_TYPE (orig_cval), cval);
     271                 :      56394 :       return cval;
     272                 :            :     }
     273                 :            :   return orig_cval;
     274                 :            : }
     275                 :            : 
     276                 :            : /* If SYM is a constant variable with known value, return the value.
     277                 :            :    NULL_TREE is returned otherwise.  */
     278                 :            : 
     279                 :            : tree
     280                 :   28281400 : get_symbol_constant_value (tree sym)
     281                 :            : {
     282                 :   28281400 :   tree val = ctor_for_folding (sym);
     283                 :   28281400 :   if (val != error_mark_node)
     284                 :            :     {
     285                 :     163151 :       if (val)
     286                 :            :         {
     287                 :     161176 :           val = canonicalize_constructor_val (unshare_expr (val), sym);
     288                 :     161176 :           if (val && is_gimple_min_invariant (val))
     289                 :            :             return val;
     290                 :            :           else
     291                 :     127630 :             return NULL_TREE;
     292                 :            :         }
     293                 :            :       /* Variables declared 'const' without an initializer
     294                 :            :          have zero as the initializer if they may not be
     295                 :            :          overridden at link or run time.  */
     296                 :       1975 :       if (!val
     297                 :       1975 :           && is_gimple_reg_type (TREE_TYPE (sym)))
     298                 :       1223 :         return build_zero_cst (TREE_TYPE (sym));
     299                 :            :     }
     300                 :            : 
     301                 :            :   return NULL_TREE;
     302                 :            : }
     303                 :            : 
     304                 :            : 
     305                 :            : 
     306                 :            : /* Subroutine of fold_stmt.  We perform several simplifications of the
     307                 :            :    memory reference tree EXPR and make sure to re-gimplify them properly
     308                 :            :    after propagation of constant addresses.  IS_LHS is true if the
     309                 :            :    reference is supposed to be an lvalue.  */
     310                 :            : 
     311                 :            : static tree
     312                 :  118487000 : maybe_fold_reference (tree expr, bool is_lhs)
     313                 :            : {
     314                 :  118487000 :   tree result;
     315                 :            : 
     316                 :  118487000 :   if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
     317                 :  118487000 :        || TREE_CODE (expr) == REALPART_EXPR
     318                 :  116156000 :        || TREE_CODE (expr) == IMAGPART_EXPR)
     319                 :  119239000 :       && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
     320                 :        252 :     return fold_unary_loc (EXPR_LOCATION (expr),
     321                 :            :                            TREE_CODE (expr),
     322                 :        126 :                            TREE_TYPE (expr),
     323                 :        252 :                            TREE_OPERAND (expr, 0));
     324                 :  118487000 :   else if (TREE_CODE (expr) == BIT_FIELD_REF
     325                 :  118487000 :            && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
     326                 :          0 :     return fold_ternary_loc (EXPR_LOCATION (expr),
     327                 :            :                              TREE_CODE (expr),
     328                 :          0 :                              TREE_TYPE (expr),
     329                 :          0 :                              TREE_OPERAND (expr, 0),
     330                 :          0 :                              TREE_OPERAND (expr, 1),
     331                 :          0 :                              TREE_OPERAND (expr, 2));
     332                 :            : 
     333                 :  118487000 :   if (!is_lhs
     334                 :   64242800 :       && (result = fold_const_aggregate_ref (expr))
     335                 :  118562000 :       && is_gimple_min_invariant (result))
     336                 :      71461 :     return result;
     337                 :            : 
     338                 :            :   return NULL_TREE;
     339                 :            : }
     340                 :            : 
     341                 :            : 
     342                 :            : /* Attempt to fold an assignment statement pointed-to by SI.  Returns a
     343                 :            :    replacement rhs for the statement or NULL_TREE if no simplification
     344                 :            :    could be made.  It is assumed that the operands have been previously
     345                 :            :    folded.  */
     346                 :            : 
     347                 :            : static tree
     348                 :  166369000 : fold_gimple_assign (gimple_stmt_iterator *si)
     349                 :            : {
     350                 :  166369000 :   gimple *stmt = gsi_stmt (*si);
     351                 :  166369000 :   enum tree_code subcode = gimple_assign_rhs_code (stmt);
     352                 :  166369000 :   location_t loc = gimple_location (stmt);
     353                 :            : 
     354                 :  166369000 :   tree result = NULL_TREE;
     355                 :            : 
     356                 :  166369000 :   switch (get_gimple_rhs_class (subcode))
     357                 :            :     {
     358                 :  115685000 :     case GIMPLE_SINGLE_RHS:
     359                 :  115685000 :       {
     360                 :  115685000 :         tree rhs = gimple_assign_rhs1 (stmt);
     361                 :            : 
     362                 :  115685000 :         if (TREE_CLOBBER_P (rhs))
     363                 :            :           return NULL_TREE;
     364                 :            : 
     365                 :  106240000 :         if (REFERENCE_CLASS_P (rhs))
     366                 :   37960100 :           return maybe_fold_reference (rhs, false);
     367                 :            : 
     368                 :   68279600 :         else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
     369                 :            :           {
     370                 :      49804 :             tree val = OBJ_TYPE_REF_EXPR (rhs);
     371                 :      49804 :             if (is_gimple_min_invariant (val))
     372                 :            :               return val;
     373                 :      49804 :             else if (flag_devirtualize && virtual_method_call_p (rhs))
     374                 :            :               {
     375                 :      49764 :                 bool final;
     376                 :      49764 :                 vec <cgraph_node *>targets
     377                 :      49764 :                   = possible_polymorphic_call_targets (rhs, stmt, &final);
     378                 :      49764 :                 if (final && targets.length () <= 1 && dbg_cnt (devirt))
     379                 :            :                   {
     380                 :         37 :                     if (dump_enabled_p ())
     381                 :            :                       {
     382                 :          0 :                         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
     383                 :            :                                          "resolving virtual function address "
     384                 :            :                                          "reference to function %s\n",
     385                 :          0 :                                          targets.length () == 1
     386                 :          0 :                                          ? targets[0]->name ()
     387                 :            :                                          : "NULL");
     388                 :            :                       }
     389                 :         37 :                     if (targets.length () == 1)
     390                 :            :                       {
     391                 :         28 :                         val = fold_convert (TREE_TYPE (val),
     392                 :            :                                             build_fold_addr_expr_loc
     393                 :            :                                               (loc, targets[0]->decl));
     394                 :         28 :                         STRIP_USELESS_TYPE_CONVERSION (val);
     395                 :            :                       }
     396                 :            :                     else
     397                 :            :                       /* We cannot use __builtin_unreachable here because it
     398                 :            :                          cannot have address taken.  */
     399                 :          9 :                       val = build_int_cst (TREE_TYPE (val), 0);
     400                 :         37 :                     return val;
     401                 :            :                   }
     402                 :            :               }
     403                 :            :           }
     404                 :            : 
     405                 :   68229800 :         else if (TREE_CODE (rhs) == ADDR_EXPR)
     406                 :            :           {
     407                 :   10379700 :             tree ref = TREE_OPERAND (rhs, 0);
     408                 :   10379700 :             tree tem = maybe_fold_reference (ref, true);
     409                 :   10379700 :             if (tem
     410                 :          0 :                 && TREE_CODE (tem) == MEM_REF
     411                 :   10379700 :                 && integer_zerop (TREE_OPERAND (tem, 1)))
     412                 :          0 :               result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (tem, 0));
     413                 :   10379700 :             else if (tem)
     414                 :          0 :               result = fold_convert (TREE_TYPE (rhs),
     415                 :            :                                      build_fold_addr_expr_loc (loc, tem));
     416                 :   10379700 :             else if (TREE_CODE (ref) == MEM_REF
     417                 :   10379700 :                      && integer_zerop (TREE_OPERAND (ref, 1)))
     418                 :       1855 :               result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0));
     419                 :            : 
     420                 :       1855 :             if (result)
     421                 :            :               {
     422                 :            :                 /* Strip away useless type conversions.  Both the
     423                 :            :                    NON_LVALUE_EXPR that may have been added by fold, and
     424                 :            :                    "useless" type conversions that might now be apparent
     425                 :            :                    due to propagation.  */
     426                 :       1855 :                 STRIP_USELESS_TYPE_CONVERSION (result);
     427                 :            : 
     428                 :       1855 :                 if (result != rhs && valid_gimple_rhs_p (result))
     429                 :       1855 :                   return result;
     430                 :            :               }
     431                 :            :           }
     432                 :            : 
     433                 :   57850100 :         else if (TREE_CODE (rhs) == CONSTRUCTOR
     434                 :   58532600 :                  && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
     435                 :            :           {
     436                 :            :             /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
     437                 :            :             unsigned i;
     438                 :            :             tree val;
     439                 :            : 
     440                 :     238368 :             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
     441                 :     116384 :               if (! CONSTANT_CLASS_P (val))
     442                 :            :                 return NULL_TREE;
     443                 :            : 
     444                 :       2803 :             return build_vector_from_ctor (TREE_TYPE (rhs),
     445                 :       2803 :                                            CONSTRUCTOR_ELTS (rhs));
     446                 :            :           }
     447                 :            : 
     448                 :   57793600 :         else if (DECL_P (rhs))
     449                 :   11875200 :           return get_symbol_constant_value (rhs);
     450                 :            :       }
     451                 :            :       break;
     452                 :            : 
     453                 :            :     case GIMPLE_UNARY_RHS:
     454                 :            :       break;
     455                 :            : 
     456                 :            :     case GIMPLE_BINARY_RHS:
     457                 :            :       break;
     458                 :            : 
     459                 :     271149 :     case GIMPLE_TERNARY_RHS:
     460                 :     271149 :       result = fold_ternary_loc (loc, subcode,
     461                 :     271149 :                                  TREE_TYPE (gimple_assign_lhs (stmt)),
     462                 :            :                                  gimple_assign_rhs1 (stmt),
     463                 :            :                                  gimple_assign_rhs2 (stmt),
     464                 :            :                                  gimple_assign_rhs3 (stmt));
     465                 :            : 
     466                 :     271149 :       if (result)
     467                 :            :         {
     468                 :      10278 :           STRIP_USELESS_TYPE_CONVERSION (result);
     469                 :      10278 :           if (valid_gimple_rhs_p (result))
     470                 :       6664 :             return result;
     471                 :            :         }
     472                 :            :       break;
     473                 :            : 
     474                 :          0 :     case GIMPLE_INVALID_RHS:
     475                 :          0 :       gcc_unreachable ();
     476                 :            :     }
     477                 :            : 
     478                 :            :   return NULL_TREE;
     479                 :            : }
     480                 :            : 
     481                 :            : 
     482                 :            : /* Replace a statement at *SI_P with a sequence of statements in STMTS,
     483                 :            :    adjusting the replacement stmts location and virtual operands.
     484                 :            :    If the statement has a lhs the last stmt in the sequence is expected
     485                 :            :    to assign to that lhs.  */
     486                 :            : 
     487                 :            : static void
     488                 :      33351 : gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
     489                 :            : {
     490                 :      33351 :   gimple *stmt = gsi_stmt (*si_p);
     491                 :            : 
     492                 :      66680 :   if (gimple_has_location (stmt))
     493                 :      33332 :     annotate_all_with_location (stmts, gimple_location (stmt));
     494                 :            : 
     495                 :            :   /* First iterate over the replacement statements backward, assigning
     496                 :            :      virtual operands to their defining statements.  */
     497                 :      33351 :   gimple *laststore = NULL;
     498                 :      33351 :   for (gimple_stmt_iterator i = gsi_last (stmts);
     499                 :     128205 :        !gsi_end_p (i); gsi_prev (&i))
     500                 :            :     {
     501                 :      47427 :       gimple *new_stmt = gsi_stmt (i);
     502                 :     104650 :       if ((gimple_assign_single_p (new_stmt)
     503                 :      22929 :            && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
     504                 :      47012 :           || (is_gimple_call (new_stmt)
     505                 :      12717 :               && (gimple_call_flags (new_stmt)
     506                 :      12717 :                   & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0))
     507                 :            :         {
     508                 :       1763 :           tree vdef;
     509                 :       1763 :           if (!laststore)
     510                 :       1631 :             vdef = gimple_vdef (stmt);
     511                 :            :           else
     512                 :        264 :             vdef = make_ssa_name (gimple_vop (cfun), new_stmt);
     513                 :       1763 :           gimple_set_vdef (new_stmt, vdef);
     514                 :       1763 :           if (vdef && TREE_CODE (vdef) == SSA_NAME)
     515                 :        961 :             SSA_NAME_DEF_STMT (vdef) = new_stmt;
     516                 :            :           laststore = new_stmt;
     517                 :            :         }
     518                 :            :     }
     519                 :            : 
     520                 :            :   /* Second iterate over the statements forward, assigning virtual
     521                 :            :      operands to their uses.  */
     522                 :      33351 :   tree reaching_vuse = gimple_vuse (stmt);
     523                 :      33351 :   for (gimple_stmt_iterator i = gsi_start (stmts);
     524                 :      80778 :        !gsi_end_p (i); gsi_next (&i))
     525                 :            :     {
     526                 :      47427 :       gimple *new_stmt = gsi_stmt (i);
     527                 :            :       /* If the new statement possibly has a VUSE, update it with exact SSA
     528                 :            :          name we know will reach this one.  */
     529                 :      47427 :       if (gimple_has_mem_ops (new_stmt))
     530                 :      47426 :         gimple_set_vuse (new_stmt, reaching_vuse);
     531                 :      47427 :       gimple_set_modified (new_stmt, true);
     532                 :      95820 :       if (gimple_vdef (new_stmt))
     533                 :        966 :         reaching_vuse = gimple_vdef (new_stmt);
     534                 :            :     }
     535                 :            : 
     536                 :            :   /* If the new sequence does not do a store release the virtual
     537                 :            :      definition of the original statement.  */
     538                 :      33351 :   if (reaching_vuse
     539                 :      49292 :       && reaching_vuse == gimple_vuse (stmt))
     540                 :            :     {
     541                 :      15112 :       tree vdef = gimple_vdef (stmt);
     542                 :      15112 :       if (vdef
     543                 :       1393 :           && TREE_CODE (vdef) == SSA_NAME)
     544                 :            :         {
     545                 :       1360 :           unlink_stmt_vdef (stmt);
     546                 :       1360 :           release_ssa_name (vdef);
     547                 :            :         }
     548                 :            :     }
     549                 :            : 
     550                 :            :   /* Finally replace the original statement with the sequence.  */
     551                 :      33351 :   gsi_replace_with_seq (si_p, stmts, false);
     552                 :      33351 : }
     553                 :            : 
     554                 :            : /* Convert EXPR into a GIMPLE value suitable for substitution on the
     555                 :            :    RHS of an assignment.  Insert the necessary statements before
     556                 :            :    iterator *SI_P.  The statement at *SI_P, which must be a GIMPLE_CALL
     557                 :            :    is replaced.  If the call is expected to produces a result, then it
     558                 :            :    is replaced by an assignment of the new RHS to the result variable.
     559                 :            :    If the result is to be ignored, then the call is replaced by a
     560                 :            :    GIMPLE_NOP.  A proper VDEF chain is retained by making the first
     561                 :            :    VUSE and the last VDEF of the whole sequence be the same as the replaced
     562                 :            :    statement and using new SSA names for stores in between.  */
     563                 :            : 
     564                 :            : void
     565                 :       3738 : gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
     566                 :            : {
     567                 :       3738 :   tree lhs;
     568                 :       3738 :   gimple *stmt, *new_stmt;
     569                 :       3738 :   gimple_stmt_iterator i;
     570                 :       3738 :   gimple_seq stmts = NULL;
     571                 :            : 
     572                 :       3738 :   stmt = gsi_stmt (*si_p);
     573                 :            : 
     574                 :       3738 :   gcc_assert (is_gimple_call (stmt));
     575                 :            : 
     576                 :       7476 :   push_gimplify_context (gimple_in_ssa_p (cfun));
     577                 :            : 
     578                 :       3738 :   lhs = gimple_call_lhs (stmt);
     579                 :       3738 :   if (lhs == NULL_TREE)
     580                 :            :     {
     581                 :        299 :       gimplify_and_add (expr, &stmts);
     582                 :            :       /* We can end up with folding a memcpy of an empty class assignment
     583                 :            :          which gets optimized away by C++ gimplification.  */
     584                 :        299 :       if (gimple_seq_empty_p (stmts))
     585                 :            :         {
     586                 :          0 :           pop_gimplify_context (NULL);
     587                 :          0 :           if (gimple_in_ssa_p (cfun))
     588                 :            :             {
     589                 :          0 :               unlink_stmt_vdef (stmt);
     590                 :          0 :               release_defs (stmt);
     591                 :            :             }
     592                 :          0 :           gsi_replace (si_p, gimple_build_nop (), false);
     593                 :          0 :           return;
     594                 :            :         }
     595                 :            :     }
     596                 :            :   else
     597                 :            :     {
     598                 :       3439 :       tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
     599                 :       3439 :       new_stmt = gimple_build_assign (lhs, tmp);
     600                 :       3439 :       i = gsi_last (stmts);
     601                 :       3439 :       gsi_insert_after_without_update (&i, new_stmt,
     602                 :            :                                        GSI_CONTINUE_LINKING);
     603                 :            :     }
     604                 :            : 
     605                 :       3738 :   pop_gimplify_context (NULL);
     606                 :            : 
     607                 :       3738 :   gsi_replace_with_seq_vops (si_p, stmts);
     608                 :            : }
     609                 :            : 
     610                 :            : 
     611                 :            : /* Replace the call at *GSI with the gimple value VAL.  */
     612                 :            : 
     613                 :            : void
     614                 :       4886 : replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
     615                 :            : {
     616                 :       4886 :   gimple *stmt = gsi_stmt (*gsi);
     617                 :       4886 :   tree lhs = gimple_call_lhs (stmt);
     618                 :       4886 :   gimple *repl;
     619                 :       4886 :   if (lhs)
     620                 :            :     {
     621                 :       1369 :       if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (val)))
     622                 :        698 :         val = fold_convert (TREE_TYPE (lhs), val);
     623                 :       1369 :       repl = gimple_build_assign (lhs, val);
     624                 :            :     }
     625                 :            :   else
     626                 :       3517 :     repl = gimple_build_nop ();
     627                 :       4886 :   tree vdef = gimple_vdef (stmt);
     628                 :       4886 :   if (vdef && TREE_CODE (vdef) == SSA_NAME)
     629                 :            :     {
     630                 :       2637 :       unlink_stmt_vdef (stmt);
     631                 :       2637 :       release_ssa_name (vdef);
     632                 :            :     }
     633                 :       4886 :   gsi_replace (gsi, repl, false);
     634                 :       4886 : }
     635                 :            : 
     636                 :            : /* Replace the call at *GSI with the new call REPL and fold that
     637                 :            :    again.  */
     638                 :            : 
     639                 :            : static void
     640                 :      24515 : replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
     641                 :            : {
     642                 :      24515 :   gimple *stmt = gsi_stmt (*gsi);
     643                 :      24515 :   gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
     644                 :      24515 :   gimple_set_location (repl, gimple_location (stmt));
     645                 :      24515 :   gimple_move_vops (repl, stmt);
     646                 :      24515 :   gsi_replace (gsi, repl, false);
     647                 :      24515 :   fold_stmt (gsi);
     648                 :      24515 : }
     649                 :            : 
     650                 :            : /* Return true if VAR is a VAR_DECL or a component thereof.  */
     651                 :            : 
     652                 :            : static bool
     653                 :     294712 : var_decl_component_p (tree var)
     654                 :            : {
     655                 :     294712 :   tree inner = var;
     656                 :     400625 :   while (handled_component_p (inner))
     657                 :     105913 :     inner = TREE_OPERAND (inner, 0);
     658                 :     294712 :   return (DECL_P (inner)
     659                 :     294712 :           || (TREE_CODE (inner) == MEM_REF
     660                 :      28622 :               && TREE_CODE (TREE_OPERAND (inner, 0)) == ADDR_EXPR));
     661                 :            : }
     662                 :            : 
     663                 :            : /* Return TRUE if the SIZE argument, representing the size of an
     664                 :            :    object, is in a range of values of which exactly zero is valid.  */
     665                 :            : 
     666                 :            : static bool
     667                 :     550278 : size_must_be_zero_p (tree size)
     668                 :            : {
     669                 :     550278 :   if (integer_zerop (size))
     670                 :            :     return true;
     671                 :            : 
     672                 :     853784 :   if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size)))
     673                 :            :     return false;
     674                 :            : 
     675                 :     305447 :   tree type = TREE_TYPE (size);
     676                 :     305447 :   int prec = TYPE_PRECISION (type);
     677                 :            : 
     678                 :            :   /* Compute the value of SSIZE_MAX, the largest positive value that
     679                 :            :      can be stored in ssize_t, the signed counterpart of size_t.  */
     680                 :     337944 :   wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
     681                 :     305447 :   value_range valid_range (build_int_cst (type, 0),
     682                 :     305447 :                            wide_int_to_tree (type, ssize_max));
     683                 :     305447 :   value_range vr;
     684                 :     305447 :   get_range_info (size, vr);
     685                 :     305447 :   vr.intersect (&valid_range);
     686                 :     305447 :   return vr.zero_p ();
     687                 :            : }
     688                 :            : 
     689                 :            : /* Fold function call to builtin mem{{,p}cpy,move}.  Try to detect and
     690                 :            :    diagnose (otherwise undefined) overlapping copies without preventing
     691                 :            :    folding.  When folded, GCC guarantees that overlapping memcpy has
     692                 :            :    the same semantics as memmove.  Call to the library memcpy need not
     693                 :            :    provide the same guarantee.  Return false if no simplification can
     694                 :            :    be made.  */
     695                 :            : 
     696                 :            : static bool
     697                 :     550278 : gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
     698                 :            :                                tree dest, tree src, enum built_in_function code)
     699                 :            : {
     700                 :     550278 :   gimple *stmt = gsi_stmt (*gsi);
     701                 :     550278 :   tree lhs = gimple_call_lhs (stmt);
     702                 :     550278 :   tree len = gimple_call_arg (stmt, 2);
     703                 :     550278 :   tree destvar, srcvar;
     704                 :     550278 :   location_t loc = gimple_location (stmt);
     705                 :            : 
     706                 :            :   /* If the LEN parameter is a constant zero or in range where
     707                 :            :      the only valid value is zero, return DEST.  */
     708                 :     550278 :   if (size_must_be_zero_p (len))
     709                 :            :     {
     710                 :       1965 :       gimple *repl;
     711                 :       1965 :       if (gimple_call_lhs (stmt))
     712                 :         48 :         repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
     713                 :            :       else
     714                 :       1917 :         repl = gimple_build_nop ();
     715                 :       1965 :       tree vdef = gimple_vdef (stmt);
     716                 :       1965 :       if (vdef && TREE_CODE (vdef) == SSA_NAME)
     717                 :            :         {
     718                 :        233 :           unlink_stmt_vdef (stmt);
     719                 :        233 :           release_ssa_name (vdef);
     720                 :            :         }
     721                 :       1965 :       gsi_replace (gsi, repl, false);
     722                 :       1965 :       return true;
     723                 :            :     }
     724                 :            : 
     725                 :            :   /* If SRC and DEST are the same (and not volatile), return
     726                 :            :      DEST{,+LEN,+LEN-1}.  */
     727                 :     548313 :   if (operand_equal_p (src, dest, 0))
     728                 :            :     {
     729                 :            :       /* Avoid diagnosing exact overlap in calls to __builtin_memcpy.
     730                 :            :          It's safe and may even be emitted by GCC itself (see bug
     731                 :            :          32667).  */
     732                 :         90 :       unlink_stmt_vdef (stmt);
     733                 :        180 :       if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
     734                 :         22 :         release_ssa_name (gimple_vdef (stmt));
     735                 :         90 :       if (!lhs)
     736                 :            :         {
     737                 :         69 :           gsi_replace (gsi, gimple_build_nop (), false);
     738                 :         69 :           return true;
     739                 :            :         }
     740                 :         21 :       goto done;
     741                 :            :     }
     742                 :            :   else
     743                 :            :     {
     744                 :     548223 :       tree srctype, desttype;
     745                 :     548223 :       unsigned int src_align, dest_align;
     746                 :     548223 :       tree off0;
     747                 :     548223 :       const char *tmp_str;
     748                 :     548223 :       unsigned HOST_WIDE_INT tmp_len;
     749                 :            : 
     750                 :            :       /* Build accesses at offset zero with a ref-all character type.  */
     751                 :     548223 :       off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
     752                 :     548223 :                                                          ptr_mode, true), 0);
     753                 :            : 
     754                 :            :       /* If we can perform the copy efficiently with first doing all loads
     755                 :            :          and then all stores inline it that way.  Currently efficiently
     756                 :            :          means that we can load all the memory into a single integer
     757                 :            :          register which is what MOVE_MAX gives us.  */
     758                 :     548223 :       src_align = get_pointer_alignment (src);
     759                 :     548223 :       dest_align = get_pointer_alignment (dest);
     760                 :     548223 :       if (tree_fits_uhwi_p (len)
     761                 :     235479 :           && compare_tree_int (len, MOVE_MAX) <= 0
     762                 :            :           /* FIXME: Don't transform copies from strings with known length.
     763                 :            :              Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c
     764                 :            :              from being handled, and the case was XFAILed for that reason.
     765                 :            :              Now that it is handled and the XFAIL removed, as soon as other
     766                 :            :              strlenopt tests that rely on it for passing are adjusted, this
     767                 :            :              hack can be removed.  */
     768                 :     169141 :           && !c_strlen (src, 1)
     769                 :     657887 :           && !((tmp_str = c_getstr (src, &tmp_len)) != NULL
     770                 :      62170 :                && memchr (tmp_str, 0, tmp_len) == NULL))
     771                 :            :         {
     772                 :      53155 :           unsigned ilen = tree_to_uhwi (len);
     773                 :      53155 :           if (pow2p_hwi (ilen))
     774                 :            :             {
     775                 :            :               /* Detect out-of-bounds accesses without issuing warnings.
     776                 :            :                  Avoid folding out-of-bounds copies but to avoid false
     777                 :            :                  positives for unreachable code defer warning until after
     778                 :            :                  DCE has worked its magic.
     779                 :            :                  -Wrestrict is still diagnosed.  */
     780                 :      14382 :               if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
     781                 :            :                                                          dest, src, len, len,
     782                 :            :                                                          false, false))
     783                 :       1054 :                 if (warning != OPT_Wrestrict)
     784                 :     546936 :                   return false;
     785                 :            : 
     786                 :      13393 :               scalar_int_mode mode;
     787                 :      13393 :               tree type = lang_hooks.types.type_for_size (ilen * 8, 1);
     788                 :      13393 :               if (type
     789                 :      25938 :                   && is_a <scalar_int_mode> (TYPE_MODE (type), &mode)
     790                 :      12969 :                   && GET_MODE_SIZE (mode) * BITS_PER_UNIT == ilen * 8
     791                 :            :                   /* If the destination pointer is not aligned we must be able
     792                 :            :                      to emit an unaligned store.  */
     793                 :      26362 :                   && (dest_align >= GET_MODE_ALIGNMENT (mode)
     794                 :       8174 :                       || !targetm.slow_unaligned_access (mode, dest_align)
     795                 :          0 :                       || (optab_handler (movmisalign_optab, mode)
     796                 :            :                           != CODE_FOR_nothing)))
     797                 :            :                 {
     798                 :      12969 :                   tree srctype = type;
     799                 :      12969 :                   tree desttype = type;
     800                 :      12969 :                   if (src_align < GET_MODE_ALIGNMENT (mode))
     801                 :       8208 :                     srctype = build_aligned_type (type, src_align);
     802                 :      12969 :                   tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
     803                 :      12969 :                   tree tem = fold_const_aggregate_ref (srcmem);
     804                 :      12969 :                   if (tem)
     805                 :            :                     srcmem = tem;
     806                 :      12442 :                   else if (src_align < GET_MODE_ALIGNMENT (mode)
     807                 :       8048 :                            && targetm.slow_unaligned_access (mode, src_align)
     808                 :      12442 :                            && (optab_handler (movmisalign_optab, mode)
     809                 :            :                                == CODE_FOR_nothing))
     810                 :            :                     srcmem = NULL_TREE;
     811                 :      12969 :                   if (srcmem)
     812                 :            :                     {
     813                 :      12969 :                       gimple *new_stmt;
     814                 :      12969 :                       if (is_gimple_reg_type (TREE_TYPE (srcmem)))
     815                 :            :                         {
     816                 :      12969 :                           new_stmt = gimple_build_assign (NULL_TREE, srcmem);
     817                 :      12969 :                           srcmem
     818                 :      12969 :                             = create_tmp_reg_or_ssa_name (TREE_TYPE (srcmem),
     819                 :            :                                                           new_stmt);
     820                 :      12969 :                           gimple_assign_set_lhs (new_stmt, srcmem);
     821                 :      25938 :                           gimple_set_vuse (new_stmt, gimple_vuse (stmt));
     822                 :      12969 :                           gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
     823                 :            :                         }
     824                 :      12969 :                       if (dest_align < GET_MODE_ALIGNMENT (mode))
     825                 :       8174 :                         desttype = build_aligned_type (type, dest_align);
     826                 :      12969 :                       new_stmt
     827                 :      12969 :                         = gimple_build_assign (fold_build2 (MEM_REF, desttype,
     828                 :            :                                                             dest, off0),
     829                 :            :                                                srcmem);
     830                 :      12969 :                       gimple_move_vops (new_stmt, stmt);
     831                 :      12969 :                       if (!lhs)
     832                 :            :                         {
     833                 :      11826 :                           gsi_replace (gsi, new_stmt, false);
     834                 :      11826 :                           return true;
     835                 :            :                         }
     836                 :       1143 :                       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
     837                 :       1143 :                       goto done;
     838                 :            :                     }
     839                 :            :                 }
     840                 :            :             }
     841                 :            :         }
     842                 :            : 
     843                 :     534265 :       if (code == BUILT_IN_MEMMOVE)
     844                 :            :         {
     845                 :            :           /* Both DEST and SRC must be pointer types.
     846                 :            :              ??? This is what old code did.  Is the testing for pointer types
     847                 :            :              really mandatory?
     848                 :            : 
     849                 :            :              If either SRC is readonly or length is 1, we can use memcpy.  */
     850                 :     168902 :           if (!dest_align || !src_align)
     851                 :            :             return false;
     852                 :     168902 :           if (readonly_data_expr (src)
     853                 :     168902 :               || (tree_fits_uhwi_p (len)
     854                 :      14338 :                   && (MIN (src_align, dest_align) / BITS_PER_UNIT
     855                 :      14338 :                       >= tree_to_uhwi (len))))
     856                 :            :             {
     857                 :     562989 :               tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
     858                 :      16053 :               if (!fn)
     859                 :            :                 return false;
     860                 :      16053 :               gimple_call_set_fndecl (stmt, fn);
     861                 :      16053 :               gimple_call_set_arg (stmt, 0, dest);
     862                 :      16053 :               gimple_call_set_arg (stmt, 1, src);
     863                 :      16053 :               fold_stmt (gsi);
     864                 :      16053 :               return true;
     865                 :            :             }
     866                 :            : 
     867                 :            :           /* If *src and *dest can't overlap, optimize into memcpy as well.  */
     868                 :     152849 :           if (TREE_CODE (src) == ADDR_EXPR
     869                 :       4729 :               && TREE_CODE (dest) == ADDR_EXPR)
     870                 :            :             {
     871                 :       1540 :               tree src_base, dest_base, fn;
     872                 :       1540 :               poly_int64 src_offset = 0, dest_offset = 0;
     873                 :       1540 :               poly_uint64 maxsize;
     874                 :            : 
     875                 :       1540 :               srcvar = TREE_OPERAND (src, 0);
     876                 :       1540 :               src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
     877                 :       1540 :               if (src_base == NULL)
     878                 :          0 :                 src_base = srcvar;
     879                 :       1540 :               destvar = TREE_OPERAND (dest, 0);
     880                 :       1540 :               dest_base = get_addr_base_and_unit_offset (destvar,
     881                 :            :                                                          &dest_offset);
     882                 :       1540 :               if (dest_base == NULL)
     883                 :          0 :                 dest_base = destvar;
     884                 :       1540 :               if (!poly_int_tree_p (len, &maxsize))
     885                 :        114 :                 maxsize = -1;
     886                 :       1540 :               if (SSA_VAR_P (src_base)
     887                 :       1530 :                   && SSA_VAR_P (dest_base))
     888                 :            :                 {
     889                 :       1530 :                   if (operand_equal_p (src_base, dest_base, 0)
     890                 :       1530 :                       && ranges_maybe_overlap_p (src_offset, maxsize,
     891                 :            :                                                  dest_offset, maxsize))
     892                 :            :                     return false;
     893                 :            :                 }
     894                 :         10 :               else if (TREE_CODE (src_base) == MEM_REF
     895                 :          0 :                        && TREE_CODE (dest_base) == MEM_REF)
     896                 :            :                 {
     897                 :          0 :                   if (! operand_equal_p (TREE_OPERAND (src_base, 0),
     898                 :          0 :                                          TREE_OPERAND (dest_base, 0), 0))
     899                 :          0 :                     return false;
     900                 :          0 :                   poly_offset_int full_src_offset
     901                 :          0 :                     = mem_ref_offset (src_base) + src_offset;
     902                 :          0 :                   poly_offset_int full_dest_offset
     903                 :          0 :                     = mem_ref_offset (dest_base) + dest_offset;
     904                 :          0 :                   if (ranges_maybe_overlap_p (full_src_offset, maxsize,
     905                 :            :                                               full_dest_offset, maxsize))
     906                 :          0 :                     return false;
     907                 :            :                 }
     908                 :            :               else
     909                 :            :                 return false;
     910                 :            : 
     911                 :       2708 :               fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
     912                 :       1168 :               if (!fn)
     913                 :            :                 return false;
     914                 :       1168 :               gimple_call_set_fndecl (stmt, fn);
     915                 :       1168 :               gimple_call_set_arg (stmt, 0, dest);
     916                 :       1168 :               gimple_call_set_arg (stmt, 1, src);
     917                 :       1168 :               fold_stmt (gsi);
     918                 :       1168 :               return true;
     919                 :            :             }
     920                 :            : 
     921                 :            :           /* If the destination and source do not alias optimize into
     922                 :            :              memcpy as well.  */
     923                 :     151309 :           if ((is_gimple_min_invariant (dest)
     924                 :     148079 :                || TREE_CODE (dest) == SSA_NAME)
     925                 :     294605 :               && (is_gimple_min_invariant (src)
     926                 :     143434 :                   || TREE_CODE (src) == SSA_NAME))
     927                 :            :             {
     928                 :     144183 :               ao_ref destr, srcr;
     929                 :     144183 :               ao_ref_init_from_ptr_and_size (&destr, dest, len);
     930                 :     144183 :               ao_ref_init_from_ptr_and_size (&srcr, src, len);
     931                 :     144183 :               if (!refs_may_alias_p_1 (&destr, &srcr, false))
     932                 :            :                 {
     933                 :       5473 :                   tree fn;
     934                 :       5473 :                   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
     935                 :       5473 :                   if (!fn)
     936                 :       5473 :                     return false;
     937                 :       5473 :                   gimple_call_set_fndecl (stmt, fn);
     938                 :       5473 :                   gimple_call_set_arg (stmt, 0, dest);
     939                 :       5473 :                   gimple_call_set_arg (stmt, 1, src);
     940                 :       5473 :                   fold_stmt (gsi);
     941                 :       5473 :                   return true;
     942                 :            :                 }
     943                 :            :             }
     944                 :            : 
     945                 :     145836 :           return false;
     946                 :            :         }
     947                 :            : 
     948                 :     365363 :       if (!tree_fits_shwi_p (len))
     949                 :            :         return false;
     950                 :     194090 :       if (!POINTER_TYPE_P (TREE_TYPE (src))
     951                 :     387638 :           || !POINTER_TYPE_P (TREE_TYPE (dest)))
     952                 :            :         return false;
     953                 :            :       /* In the following try to find a type that is most natural to be
     954                 :            :          used for the memcpy source and destination and that allows
     955                 :            :          the most optimization when memcpy is turned into a plain assignment
     956                 :            :          using that type.  In theory we could always use a char[len] type
     957                 :            :          but that only gains us that the destination and source possibly
     958                 :            :          no longer will have their address taken.  */
     959                 :     193819 :       srctype = TREE_TYPE (TREE_TYPE (src));
     960                 :     193819 :       if (TREE_CODE (srctype) == ARRAY_TYPE
     961                 :     298782 :           && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
     962                 :      69246 :         srctype = TREE_TYPE (srctype);
     963                 :     193819 :       desttype = TREE_TYPE (TREE_TYPE (dest));
     964                 :     193819 :       if (TREE_CODE (desttype) == ARRAY_TYPE
     965                 :     323579 :           && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
     966                 :      85263 :         desttype = TREE_TYPE (desttype);
     967                 :     193819 :       if (TREE_ADDRESSABLE (srctype)
     968                 :     193819 :           || TREE_ADDRESSABLE (desttype))
     969                 :            :         return false;
     970                 :            : 
     971                 :            :       /* Make sure we are not copying using a floating-point mode or
     972                 :            :          a type whose size possibly does not match its precision.  */
     973                 :     773698 :       if (FLOAT_MODE_P (TYPE_MODE (desttype))
     974                 :     193295 :           || TREE_CODE (desttype) == BOOLEAN_TYPE
     975                 :     387098 :           || TREE_CODE (desttype) == ENUMERAL_TYPE)
     976                 :        508 :         desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
     977                 :     773847 :       if (FLOAT_MODE_P (TYPE_MODE (srctype))
     978                 :     193206 :           || TREE_CODE (srctype) == BOOLEAN_TYPE
     979                 :     387005 :           || TREE_CODE (srctype) == ENUMERAL_TYPE)
     980                 :        601 :         srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
     981                 :     193803 :       if (!srctype)
     982                 :        140 :         srctype = desttype;
     983                 :     193803 :       if (!desttype)
     984                 :          0 :         desttype = srctype;
     985                 :     193803 :       if (!srctype)
     986                 :            :         return false;
     987                 :            : 
     988                 :     193803 :       src_align = get_pointer_alignment (src);
     989                 :     193803 :       dest_align = get_pointer_alignment (dest);
     990                 :            : 
     991                 :            :       /* Choose between src and destination type for the access based
     992                 :            :          on alignment, whether the access constitutes a register access
     993                 :            :          and whether it may actually expose a declaration for SSA rewrite
     994                 :            :          or SRA decomposition.  */
     995                 :     193803 :       destvar = NULL_TREE;
     996                 :     193803 :       srcvar = NULL_TREE;
     997                 :     193803 :       if (TREE_CODE (dest) == ADDR_EXPR
     998                 :      81144 :           && var_decl_component_p (TREE_OPERAND (dest, 0))
     999                 :      81144 :           && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)
    1000                 :      15257 :           && dest_align >= TYPE_ALIGN (desttype)
    1001                 :     209060 :           && (is_gimple_reg_type (desttype)
    1002                 :      14867 :               || src_align >= TYPE_ALIGN (desttype)))
    1003                 :      13082 :         destvar = fold_build2 (MEM_REF, desttype, dest, off0);
    1004                 :     180721 :       else if (TREE_CODE (src) == ADDR_EXPR
    1005                 :     157935 :                && var_decl_component_p (TREE_OPERAND (src, 0))
    1006                 :      39757 :                && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
    1007                 :       4847 :                && src_align >= TYPE_ALIGN (srctype)
    1008                 :     185550 :                && (is_gimple_reg_type (srctype)
    1009                 :       4645 :                    || dest_align >= TYPE_ALIGN (srctype)))
    1010                 :       1634 :         srcvar = fold_build2 (MEM_REF, srctype, src, off0);
    1011                 :     193803 :       if (srcvar == NULL_TREE && destvar == NULL_TREE)
    1012                 :            :         return false;
    1013                 :            : 
    1014                 :            :       /* Now that we chose an access type express the other side in
    1015                 :            :          terms of it if the target allows that with respect to alignment
    1016                 :            :          constraints.  */
    1017                 :      14716 :       if (srcvar == NULL_TREE)
    1018                 :            :         {
    1019                 :      13082 :           if (src_align >= TYPE_ALIGN (desttype))
    1020                 :      13068 :             srcvar = fold_build2 (MEM_REF, desttype, src, off0);
    1021                 :            :           else
    1022                 :            :             {
    1023                 :         14 :               if (STRICT_ALIGNMENT)
    1024                 :            :                 return false;
    1025                 :         14 :               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
    1026                 :            :                                             src_align);
    1027                 :         14 :               srcvar = fold_build2 (MEM_REF, srctype, src, off0);
    1028                 :            :             }
    1029                 :            :         }
    1030                 :       1634 :       else if (destvar == NULL_TREE)
    1031                 :            :         {
    1032                 :       1634 :           if (dest_align >= TYPE_ALIGN (srctype))
    1033                 :       1630 :             destvar = fold_build2 (MEM_REF, srctype, dest, off0);
    1034                 :            :           else
    1035                 :            :             {
    1036                 :          4 :               if (STRICT_ALIGNMENT)
    1037                 :            :                 return false;
    1038                 :          4 :               desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
    1039                 :            :                                              dest_align);
    1040                 :          4 :               destvar = fold_build2 (MEM_REF, desttype, dest, off0);
    1041                 :            :             }
    1042                 :            :         }
    1043                 :            : 
    1044                 :            :       /* Same as above, detect out-of-bounds accesses without issuing
    1045                 :            :          warnings.  Avoid folding out-of-bounds copies but to avoid
    1046                 :            :          false positives for unreachable code defer warning until
    1047                 :            :          after DCE has worked its magic.
    1048                 :            :          -Wrestrict is still diagnosed.  */
    1049                 :      14716 :       if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
    1050                 :            :                                                  dest, src, len, len,
    1051                 :            :                                                  false, false))
    1052                 :        113 :         if (warning != OPT_Wrestrict)
    1053                 :            :           return false;
    1054                 :            : 
    1055                 :      14613 :       gimple *new_stmt;
    1056                 :      14613 :       if (is_gimple_reg_type (TREE_TYPE (srcvar)))
    1057                 :            :         {
    1058                 :        511 :           tree tem = fold_const_aggregate_ref (srcvar);
    1059                 :        511 :           if (tem)
    1060                 :        498 :             srcvar = tem;
    1061                 :        511 :           if (! is_gimple_min_invariant (srcvar))
    1062                 :            :             {
    1063                 :         13 :               new_stmt = gimple_build_assign (NULL_TREE, srcvar);
    1064                 :         13 :               srcvar = create_tmp_reg_or_ssa_name (TREE_TYPE (srcvar),
    1065                 :            :                                                    new_stmt);
    1066                 :         13 :               gimple_assign_set_lhs (new_stmt, srcvar);
    1067                 :         26 :               gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    1068                 :         13 :               gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    1069                 :            :             }
    1070                 :        511 :           new_stmt = gimple_build_assign (destvar, srcvar);
    1071                 :        511 :           goto set_vop_and_replace;
    1072                 :            :         }
    1073                 :            : 
    1074                 :            :       /* We get an aggregate copy.  Use an unsigned char[] type to
    1075                 :            :          perform the copying to preserve padding and to avoid any issues
    1076                 :            :          with TREE_ADDRESSABLE types or float modes behavior on copying.  */
    1077                 :      28204 :       desttype = build_array_type_nelts (unsigned_char_type_node,
    1078                 :      14102 :                                          tree_to_uhwi (len));
    1079                 :      14102 :       srctype = desttype;
    1080                 :      14102 :       if (src_align > TYPE_ALIGN (srctype))
    1081                 :       7017 :         srctype = build_aligned_type (srctype, src_align);
    1082                 :      14102 :       if (dest_align > TYPE_ALIGN (desttype))
    1083                 :       7399 :         desttype = build_aligned_type (desttype, dest_align);
    1084                 :      14102 :       new_stmt
    1085                 :      14102 :         = gimple_build_assign (fold_build2 (MEM_REF, desttype, dest, off0),
    1086                 :            :                                fold_build2 (MEM_REF, srctype, src, off0));
    1087                 :      14613 : set_vop_and_replace:
    1088                 :      14613 :       gimple_move_vops (new_stmt, stmt);
    1089                 :      14613 :       if (!lhs)
    1090                 :            :         {
    1091                 :      14469 :           gsi_replace (gsi, new_stmt, false);
    1092                 :      14469 :           return true;
    1093                 :            :         }
    1094                 :        144 :       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    1095                 :            :     }
    1096                 :            : 
    1097                 :       1308 : done:
    1098                 :       1308 :   gimple_seq stmts = NULL;
    1099                 :       1308 :   if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
    1100                 :       1308 :     len = NULL_TREE;
    1101                 :        185 :   else if (code == BUILT_IN_MEMPCPY)
    1102                 :            :     {
    1103                 :        185 :       len = gimple_convert_to_ptrofftype (&stmts, loc, len);
    1104                 :        185 :       dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
    1105                 :        185 :                            TREE_TYPE (dest), dest, len);
    1106                 :            :     }
    1107                 :            :   else
    1108                 :          0 :     gcc_unreachable ();
    1109                 :            : 
    1110                 :       1308 :   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    1111                 :       1308 :   gimple *repl = gimple_build_assign (lhs, dest);
    1112                 :       1308 :   gsi_replace (gsi, repl, false);
    1113                 :       1308 :   return true;
    1114                 :            : }
    1115                 :            : 
    1116                 :            : /* Transform a call to built-in bcmp(a, b, len) at *GSI into one
    1117                 :            :    to built-in memcmp (a, b, len).  */
    1118                 :            : 
    1119                 :            : static bool
    1120                 :        135 : gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
    1121                 :            : {
    1122                 :        135 :   tree fn = builtin_decl_implicit (BUILT_IN_MEMCMP);
    1123                 :            : 
    1124                 :        135 :   if (!fn)
    1125                 :            :     return false;
    1126                 :            : 
    1127                 :            :   /* Transform bcmp (a, b, len) into memcmp (a, b, len).  */
    1128                 :            : 
    1129                 :        135 :   gimple *stmt = gsi_stmt (*gsi);
    1130                 :        135 :   tree a = gimple_call_arg (stmt, 0);
    1131                 :        135 :   tree b = gimple_call_arg (stmt, 1);
    1132                 :        135 :   tree len = gimple_call_arg (stmt, 2);
    1133                 :            : 
    1134                 :        135 :   gimple *repl = gimple_build_call (fn, 3, a, b, len);
    1135                 :        135 :   replace_call_with_call_and_fold (gsi, repl);
    1136                 :            : 
    1137                 :        135 :   return true;
    1138                 :            : }
    1139                 :            : 
    1140                 :            : /* Transform a call to built-in bcopy (src, dest, len) at *GSI into one
    1141                 :            :    to built-in memmove (dest, src, len).  */
    1142                 :            : 
    1143                 :            : static bool
    1144                 :        331 : gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
    1145                 :            : {
    1146                 :        331 :   tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
    1147                 :            : 
    1148                 :        331 :   if (!fn)
    1149                 :            :     return false;
    1150                 :            : 
    1151                 :            :   /* bcopy has been removed from POSIX in Issue 7 but Issue 6 specifies
    1152                 :            :      it's quivalent to memmove (not memcpy).  Transform bcopy (src, dest,
    1153                 :            :      len) into memmove (dest, src, len).  */
    1154                 :            : 
    1155                 :        331 :   gimple *stmt = gsi_stmt (*gsi);
    1156                 :        331 :   tree src = gimple_call_arg (stmt, 0);
    1157                 :        331 :   tree dest = gimple_call_arg (stmt, 1);
    1158                 :        331 :   tree len = gimple_call_arg (stmt, 2);
    1159                 :            : 
    1160                 :        331 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    1161                 :        331 :   gimple_call_set_fntype (as_a <gcall *> (stmt), TREE_TYPE (fn));
    1162                 :        331 :   replace_call_with_call_and_fold (gsi, repl);
    1163                 :            : 
    1164                 :        331 :   return true;
    1165                 :            : }
    1166                 :            : 
    1167                 :            : /* Transform a call to built-in bzero (dest, len) at *GSI into one
    1168                 :            :    to built-in memset (dest, 0, len).  */
    1169                 :            : 
    1170                 :            : static bool
    1171                 :        277 : gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
    1172                 :            : {
    1173                 :        277 :   tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
    1174                 :            : 
    1175                 :        277 :   if (!fn)
    1176                 :            :     return false;
    1177                 :            : 
    1178                 :            :   /* Transform bzero (dest, len) into memset (dest, 0, len).  */
    1179                 :            : 
    1180                 :        277 :   gimple *stmt = gsi_stmt (*gsi);
    1181                 :        277 :   tree dest = gimple_call_arg (stmt, 0);
    1182                 :        277 :   tree len = gimple_call_arg (stmt, 1);
    1183                 :            : 
    1184                 :        277 :   gimple_seq seq = NULL;
    1185                 :        277 :   gimple *repl = gimple_build_call (fn, 3, dest, integer_zero_node, len);
    1186                 :        277 :   gimple_seq_add_stmt_without_update (&seq, repl);
    1187                 :        277 :   gsi_replace_with_seq_vops (gsi, seq);
    1188                 :        277 :   fold_stmt (gsi);
    1189                 :            : 
    1190                 :        277 :   return true;
    1191                 :            : }
    1192                 :            : 
    1193                 :            : /* Fold function call to builtin memset or bzero at *GSI setting the
    1194                 :            :    memory of size LEN to VAL.  Return whether a simplification was made.  */
    1195                 :            : 
    1196                 :            : static bool
    1197                 :     216912 : gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
    1198                 :            : {
    1199                 :     216912 :   gimple *stmt = gsi_stmt (*gsi);
    1200                 :     216912 :   tree etype;
    1201                 :     216912 :   unsigned HOST_WIDE_INT length, cval;
    1202                 :            : 
    1203                 :            :   /* If the LEN parameter is zero, return DEST.  */
    1204                 :     216912 :   if (integer_zerop (len))
    1205                 :            :     {
    1206                 :        775 :       replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
    1207                 :        775 :       return true;
    1208                 :            :     }
    1209                 :            : 
    1210                 :     216137 :   if (! tree_fits_uhwi_p (len))
    1211                 :            :     return false;
    1212                 :            : 
    1213                 :     143744 :   if (TREE_CODE (c) != INTEGER_CST)
    1214                 :            :     return false;
    1215                 :            : 
    1216                 :     138156 :   tree dest = gimple_call_arg (stmt, 0);
    1217                 :     138156 :   tree var = dest;
    1218                 :     138156 :   if (TREE_CODE (var) != ADDR_EXPR)
    1219                 :            :     return false;
    1220                 :            : 
    1221                 :     111639 :   var = TREE_OPERAND (var, 0);
    1222                 :     111639 :   if (TREE_THIS_VOLATILE (var))
    1223                 :            :     return false;
    1224                 :            : 
    1225                 :     111595 :   etype = TREE_TYPE (var);
    1226                 :     111595 :   if (TREE_CODE (etype) == ARRAY_TYPE)
    1227                 :      67485 :     etype = TREE_TYPE (etype);
    1228                 :            : 
    1229                 :     111595 :   if (!INTEGRAL_TYPE_P (etype)
    1230                 :      56216 :       && !POINTER_TYPE_P (etype))
    1231                 :            :     return NULL_TREE;
    1232                 :            : 
    1233                 :      55633 :   if (! var_decl_component_p (var))
    1234                 :            :     return NULL_TREE;
    1235                 :            : 
    1236                 :      55633 :   length = tree_to_uhwi (len);
    1237                 :      55633 :   if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
    1238                 :        524 :       || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
    1239                 :       1048 :           != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
    1240                 :      56157 :       || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
    1241                 :      55109 :     return NULL_TREE;
    1242                 :            : 
    1243                 :        524 :   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
    1244                 :            :     return NULL_TREE;
    1245                 :            : 
    1246                 :        524 :   if (!type_has_mode_precision_p (etype))
    1247                 :         14 :     etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype),
    1248                 :          7 :                                             TYPE_UNSIGNED (etype));
    1249                 :            : 
    1250                 :        524 :   if (integer_zerop (c))
    1251                 :            :     cval = 0;
    1252                 :            :   else
    1253                 :            :     {
    1254                 :        286 :       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
    1255                 :            :         return NULL_TREE;
    1256                 :            : 
    1257                 :        286 :       cval = TREE_INT_CST_LOW (c);
    1258                 :        286 :       cval &= 0xff;
    1259                 :        286 :       cval |= cval << 8;
    1260                 :        286 :       cval |= cval << 16;
    1261                 :        286 :       cval |= (cval << 31) << 1;
    1262                 :            :     }
    1263                 :            : 
    1264                 :        524 :   var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
    1265                 :        524 :   gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
    1266                 :        524 :   gimple_move_vops (store, stmt);
    1267                 :        524 :   gsi_insert_before (gsi, store, GSI_SAME_STMT);
    1268                 :        524 :   if (gimple_call_lhs (stmt))
    1269                 :            :     {
    1270                 :          6 :       gimple *asgn = gimple_build_assign (gimple_call_lhs (stmt), dest);
    1271                 :          6 :       gsi_replace (gsi, asgn, false);
    1272                 :            :     }
    1273                 :            :   else
    1274                 :            :     {
    1275                 :        518 :       gimple_stmt_iterator gsi2 = *gsi;
    1276                 :        518 :       gsi_prev (gsi);
    1277                 :        518 :       gsi_remove (&gsi2, true);
    1278                 :            :     }
    1279                 :            : 
    1280                 :            :   return true;
    1281                 :            : }
    1282                 :            : 
    1283                 :            : /* Helper of get_range_strlen for ARG that is not an SSA_NAME.  */
    1284                 :            : 
    1285                 :            : static bool
    1286                 :     160683 : get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
    1287                 :            :                        c_strlen_data *pdata, unsigned eltsize)
    1288                 :            : {
    1289                 :     160683 :   gcc_assert (TREE_CODE (arg) != SSA_NAME);
    1290                 :            : 
    1291                 :            :   /* The length computed by this invocation of the function.  */
    1292                 :     160683 :   tree val = NULL_TREE;
    1293                 :            : 
    1294                 :            :   /* True if VAL is an optimistic (tight) bound determined from
    1295                 :            :      the size of the character array in which the string may be
    1296                 :            :      stored.  In that case, the computed VAL is used to set
    1297                 :            :      PDATA->MAXBOUND.  */
    1298                 :     160683 :   bool tight_bound = false;
    1299                 :            : 
    1300                 :            :   /* We can end up with &(*iftmp_1)[0] here as well, so handle it.  */
    1301                 :     160683 :   if (TREE_CODE (arg) == ADDR_EXPR
    1302                 :     160683 :       && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
    1303                 :            :     {
    1304                 :      15175 :       tree op = TREE_OPERAND (arg, 0);
    1305                 :      15175 :       if (integer_zerop (TREE_OPERAND (op, 1)))
    1306                 :            :         {
    1307                 :       6097 :           tree aop0 = TREE_OPERAND (op, 0);
    1308                 :       6097 :           if (TREE_CODE (aop0) == INDIRECT_REF
    1309                 :       6097 :               && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
    1310                 :          0 :             return get_range_strlen (TREE_OPERAND (aop0, 0), visited, rkind,
    1311                 :          0 :                                      pdata, eltsize);
    1312                 :            :         }
    1313                 :       9078 :       else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
    1314                 :       9078 :                && rkind == SRK_LENRANGE)
    1315                 :            :         {
    1316                 :            :           /* Fail if an array is the last member of a struct object
    1317                 :            :              since it could be treated as a (fake) flexible array
    1318                 :            :              member.  */
    1319                 :       4239 :           tree idx = TREE_OPERAND (op, 1);
    1320                 :            : 
    1321                 :       4239 :           arg = TREE_OPERAND (op, 0);
    1322                 :       4239 :           tree optype = TREE_TYPE (arg);
    1323                 :       4239 :           if (tree dom = TYPE_DOMAIN (optype))
    1324                 :       4239 :             if (tree bound = TYPE_MAX_VALUE (dom))
    1325                 :       4239 :               if (TREE_CODE (bound) == INTEGER_CST
    1326                 :       4239 :                   && TREE_CODE (idx) == INTEGER_CST
    1327                 :       7046 :                   && tree_int_cst_lt (bound, idx))
    1328                 :            :                 return false;
    1329                 :            :         }
    1330                 :            :     }
    1331                 :            : 
    1332                 :     160452 :   if (rkind == SRK_INT_VALUE)
    1333                 :            :     {
    1334                 :            :       /* We are computing the maximum value (not string length).  */
    1335                 :      15331 :       val = arg;
    1336                 :      15331 :       if (TREE_CODE (val) != INTEGER_CST
    1337                 :      15331 :           || tree_int_cst_sgn (val) < 0)
    1338                 :       2124 :         return false;
    1339                 :            :     }
    1340                 :            :   else
    1341                 :            :     {
    1342                 :     145121 :       c_strlen_data lendata = { };
    1343                 :     145121 :       val = c_strlen (arg, 1, &lendata, eltsize);
    1344                 :            : 
    1345                 :     145121 :       if (!val && lendata.decl)
    1346                 :            :         {
    1347                 :            :           /* ARG refers to an unterminated const character array.
    1348                 :            :              DATA.DECL with size DATA.LEN.  */
    1349                 :       4306 :           val = lendata.minlen;
    1350                 :       4306 :           pdata->decl = lendata.decl;
    1351                 :            :         }
    1352                 :            :     }
    1353                 :            : 
    1354                 :            :   /* Set if VAL represents the maximum length based on array size (set
    1355                 :            :      when exact length cannot be determined).  */
    1356                 :     158328 :   bool maxbound = false;
    1357                 :            : 
    1358                 :     158328 :   if (!val && rkind == SRK_LENRANGE)
    1359                 :            :     {
    1360                 :     103049 :       if (TREE_CODE (arg) == ADDR_EXPR)
    1361                 :      35302 :         return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
    1362                 :      35302 :                                  pdata, eltsize);
    1363                 :            : 
    1364                 :      67747 :       if (TREE_CODE (arg) == ARRAY_REF)
    1365                 :            :         {
    1366                 :       9136 :           tree optype = TREE_TYPE (TREE_OPERAND (arg, 0));
    1367                 :            : 
    1368                 :            :           /* Determine the "innermost" array type.  */
    1369                 :      12539 :           while (TREE_CODE (optype) == ARRAY_TYPE
    1370                 :      12539 :                  && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
    1371                 :      12539 :             optype = TREE_TYPE (optype);
    1372                 :            : 
    1373                 :            :           /* Avoid arrays of pointers.  */
    1374                 :       9136 :           tree eltype = TREE_TYPE (optype);
    1375                 :       9136 :           if (TREE_CODE (optype) != ARRAY_TYPE
    1376                 :       9136 :               || !INTEGRAL_TYPE_P (eltype))
    1377                 :            :             return false;
    1378                 :            : 
    1379                 :            :           /* Fail when the array bound is unknown or zero.  */
    1380                 :       8370 :           val = TYPE_SIZE_UNIT (optype);
    1381                 :       8370 :           if (!val
    1382                 :       8298 :               || TREE_CODE (val) != INTEGER_CST
    1383                 :      16644 :               || integer_zerop (val))
    1384                 :         99 :             return false;
    1385                 :            : 
    1386                 :       8271 :           val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
    1387                 :            :                               integer_one_node);
    1388                 :            : 
    1389                 :            :           /* Set the minimum size to zero since the string in
    1390                 :            :              the array could have zero length.  */
    1391                 :       8271 :           pdata->minlen = ssize_int (0);
    1392                 :            : 
    1393                 :       8271 :           tight_bound = true;
    1394                 :            :         }
    1395                 :      58611 :       else if (TREE_CODE (arg) == COMPONENT_REF
    1396                 :      58611 :                && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1)))
    1397                 :            :                    == ARRAY_TYPE))
    1398                 :            :         {
    1399                 :            :           /* Use the type of the member array to determine the upper
    1400                 :            :              bound on the length of the array.  This may be overly
    1401                 :            :              optimistic if the array itself isn't NUL-terminated and
    1402                 :            :              the caller relies on the subsequent member to contain
    1403                 :            :              the NUL but that would only be considered valid if
    1404                 :            :              the array were the last member of a struct.  */
    1405                 :            : 
    1406                 :       7685 :           tree fld = TREE_OPERAND (arg, 1);
    1407                 :            : 
    1408                 :       7685 :           tree optype = TREE_TYPE (fld);
    1409                 :            : 
    1410                 :            :           /* Determine the "innermost" array type.  */
    1411                 :       7756 :           while (TREE_CODE (optype) == ARRAY_TYPE
    1412                 :       7756 :                  && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
    1413                 :       7756 :             optype = TREE_TYPE (optype);
    1414                 :            : 
    1415                 :            :           /* Fail when the array bound is unknown or zero.  */
    1416                 :       7685 :           val = TYPE_SIZE_UNIT (optype);
    1417                 :       7685 :           if (!val
    1418                 :       7491 :               || TREE_CODE (val) != INTEGER_CST
    1419                 :      15168 :               || integer_zerop (val))
    1420                 :        274 :             return false;
    1421                 :       7411 :           val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
    1422                 :            :                              integer_one_node);
    1423                 :            : 
    1424                 :            :           /* Set the minimum size to zero since the string in
    1425                 :            :              the array could have zero length.  */
    1426                 :       7411 :           pdata->minlen = ssize_int (0);
    1427                 :            : 
    1428                 :            :           /* The array size determined above is an optimistic bound
    1429                 :            :              on the length.  If the array isn't nul-terminated the
    1430                 :            :              length computed by the library function would be greater.
    1431                 :            :              Even though using strlen to cross the subobject boundary
    1432                 :            :              is undefined, avoid drawing conclusions from the member
    1433                 :            :              type about the length here.  */
    1434                 :       7411 :           tight_bound = true;
    1435                 :            :         }
    1436                 :      50926 :       else if (TREE_CODE (arg) == MEM_REF
    1437                 :      13394 :                && TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
    1438                 :       2535 :                && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == INTEGER_TYPE
    1439                 :      53410 :                && TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
    1440                 :            :         {
    1441                 :            :           /* Handle a MEM_REF into a DECL accessing an array of integers,
    1442                 :            :              being conservative about references to extern structures with
    1443                 :            :              flexible array members that can be initialized to arbitrary
    1444                 :            :              numbers of elements as an extension (static structs are okay).
    1445                 :            :              FIXME: Make this less conservative -- see
    1446                 :            :              component_ref_size in tree.c.  */
    1447                 :       2446 :           tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
    1448                 :       2446 :           if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
    1449                 :       4887 :               && (decl_binds_to_current_def_p (ref)
    1450                 :        278 :                   || !array_at_struct_end_p (arg)))
    1451                 :            :             {
    1452                 :            :               /* Fail if the offset is out of bounds.  Such accesses
    1453                 :            :                  should be diagnosed at some point.  */
    1454                 :       2405 :               val = DECL_SIZE_UNIT (ref);
    1455                 :       2405 :               if (!val
    1456                 :       2225 :                   || TREE_CODE (val) != INTEGER_CST
    1457                 :       4630 :                   || integer_zerop (val))
    1458                 :        302 :                 return false;
    1459                 :            : 
    1460                 :       2225 :               poly_offset_int psiz = wi::to_offset (val);
    1461                 :       2225 :               poly_offset_int poff = mem_ref_offset (arg);
    1462                 :       2225 :               if (known_le (psiz, poff))
    1463                 :            :                 return false;
    1464                 :            : 
    1465                 :       2103 :               pdata->minlen = ssize_int (0);
    1466                 :            : 
    1467                 :            :               /* Subtract the offset and one for the terminating nul.  */
    1468                 :       2103 :               psiz -= poff;
    1469                 :       2103 :               psiz -= 1;
    1470                 :       2103 :               val = wide_int_to_tree (TREE_TYPE (val), psiz);
    1471                 :            :               /* Since VAL reflects the size of a declared object
    1472                 :            :                  rather the type of the access it is not a tight bound.  */
    1473                 :            :             }
    1474                 :            :         }
    1475                 :      48480 :       else if (TREE_CODE (arg) == PARM_DECL || VAR_P (arg))
    1476                 :            :         {
    1477                 :            :           /* Avoid handling pointers to arrays.  GCC might misuse
    1478                 :            :              a pointer to an array of one bound to point to an array
    1479                 :            :              object of a greater bound.  */
    1480                 :      27326 :           tree argtype = TREE_TYPE (arg);
    1481                 :      27326 :           if (TREE_CODE (argtype) == ARRAY_TYPE)
    1482                 :            :             {
    1483                 :      13198 :               val = TYPE_SIZE_UNIT (argtype);
    1484                 :      13198 :               if (!val
    1485                 :      12554 :                   || TREE_CODE (val) != INTEGER_CST
    1486                 :      25752 :                   || integer_zerop (val))
    1487                 :        649 :                 return false;
    1488                 :      12549 :               val = wide_int_to_tree (TREE_TYPE (val),
    1489                 :      12549 :                                       wi::sub (wi::to_wide (val), 1));
    1490                 :            : 
    1491                 :            :               /* Set the minimum size to zero since the string in
    1492                 :            :                  the array could have zero length.  */
    1493                 :      12549 :               pdata->minlen = ssize_int (0);
    1494                 :            :             }
    1495                 :            :         }
    1496                 :            :       maxbound = true;
    1497                 :            :     }
    1498                 :            : 
    1499                 :     120936 :   if (!val)
    1500                 :            :     return false;
    1501                 :            : 
    1502                 :            :   /* Adjust the lower bound on the string length as necessary.  */
    1503                 :      65538 :   if (!pdata->minlen
    1504                 :      65538 :       || (rkind != SRK_STRLEN
    1505                 :      32915 :           && TREE_CODE (pdata->minlen) == INTEGER_CST
    1506                 :      32915 :           && TREE_CODE (val) == INTEGER_CST
    1507                 :      32910 :           && tree_int_cst_lt (val, pdata->minlen)))
    1508                 :      32210 :     pdata->minlen = val;
    1509                 :            : 
    1510                 :      65538 :   if (pdata->maxbound && TREE_CODE (pdata->maxbound) == INTEGER_CST)
    1511                 :            :     {
    1512                 :            :       /* Adjust the tighter (more optimistic) string length bound
    1513                 :            :          if necessary and proceed to adjust the more conservative
    1514                 :            :          bound.  */
    1515                 :       1114 :       if (TREE_CODE (val) == INTEGER_CST)
    1516                 :            :         {
    1517                 :       1114 :           if (tree_int_cst_lt (pdata->maxbound, val))
    1518                 :        390 :             pdata->maxbound = val;
    1519                 :            :         }
    1520                 :            :       else
    1521                 :          0 :         pdata->maxbound = val;
    1522                 :            :     }
    1523                 :      64424 :   else if (pdata->maxbound || maxbound)
    1524                 :            :     /* Set PDATA->MAXBOUND only if it either isn't INTEGER_CST or
    1525                 :            :        if VAL corresponds to the maximum length determined based
    1526                 :            :        on the type of the object.  */
    1527                 :      32152 :     pdata->maxbound = val;
    1528                 :            : 
    1529                 :      65538 :   if (tight_bound)
    1530                 :            :     {
    1531                 :            :       /* VAL computed above represents an optimistically tight bound
    1532                 :            :          on the length of the string based on the referenced object's
    1533                 :            :          or subobject's type.  Determine the conservative upper bound
    1534                 :            :          based on the enclosing object's size if possible.  */
    1535                 :      15682 :       if (rkind == SRK_LENRANGE)
    1536                 :            :         {
    1537                 :      15682 :           poly_int64 offset;
    1538                 :      15682 :           tree base = get_addr_base_and_unit_offset (arg, &offset);
    1539                 :      15682 :           if (!base)
    1540                 :            :             {
    1541                 :            :               /* When the call above fails due to a non-constant offset
    1542                 :            :                  assume the offset is zero and use the size of the whole
    1543                 :            :                  enclosing object instead.  */
    1544                 :       6458 :               base = get_base_address (arg);
    1545                 :       6458 :               offset = 0;
    1546                 :            :             }
    1547                 :            :           /* If the base object is a pointer no upper bound on the length
    1548                 :            :              can be determined.  Otherwise the maximum length is equal to
    1549                 :            :              the size of the enclosing object minus the offset of
    1550                 :            :              the referenced subobject minus 1 (for the terminating nul).  */
    1551                 :      15682 :           tree type = TREE_TYPE (base);
    1552                 :      15682 :           if (TREE_CODE (type) == POINTER_TYPE
    1553                 :      15681 :               || (TREE_CODE (base) != PARM_DECL && !VAR_P (base))
    1554                 :      29608 :               || !(val = DECL_SIZE_UNIT (base)))
    1555                 :       1813 :             val = build_all_ones_cst (size_type_node);
    1556                 :            :           else
    1557                 :            :             {
    1558                 :      13869 :               val = DECL_SIZE_UNIT (base);
    1559                 :      13869 :               val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
    1560                 :            :                                  size_int (offset + 1));
    1561                 :            :             }
    1562                 :            :         }
    1563                 :            :       else
    1564                 :            :         return false;
    1565                 :            :     }
    1566                 :            : 
    1567                 :      65538 :   if (pdata->maxlen)
    1568                 :            :     {
    1569                 :            :       /* Adjust the more conservative bound if possible/necessary
    1570                 :            :          and fail otherwise.  */
    1571                 :       4350 :       if (rkind != SRK_STRLEN)
    1572                 :            :         {
    1573                 :       3247 :           if (TREE_CODE (pdata->maxlen) != INTEGER_CST
    1574                 :       3247 :               || TREE_CODE (val) != INTEGER_CST)
    1575                 :            :             return false;
    1576                 :            : 
    1577                 :       3242 :           if (tree_int_cst_lt (pdata->maxlen, val))
    1578                 :        754 :             pdata->maxlen = val;
    1579                 :       3242 :           return true;
    1580                 :            :         }
    1581                 :       1103 :       else if (simple_cst_equal (val, pdata->maxlen) != 1)
    1582                 :            :         {
    1583                 :            :           /* Fail if the length of this ARG is different from that
    1584                 :            :              previously determined from another ARG.  */
    1585                 :            :           return false;
    1586                 :            :         }
    1587                 :            :     }
    1588                 :            : 
    1589                 :      61327 :   pdata->maxlen = val;
    1590                 :      61327 :   return rkind == SRK_LENRANGE || !integer_all_onesp (val);
    1591                 :            : }
    1592                 :            : 
    1593                 :            : /* For an ARG referencing one or more strings, try to obtain the range
    1594                 :            :    of their lengths, or the size of the largest array ARG referes to if
    1595                 :            :    the range of lengths cannot be determined, and store all in *PDATA.
    1596                 :            :    For an integer ARG (when RKIND == SRK_INT_VALUE), try to determine
    1597                 :            :    the maximum constant value.
    1598                 :            :    If ARG is an SSA_NAME, follow its use-def chains.  When RKIND ==
    1599                 :            :    SRK_STRLEN, then if PDATA->MAXLEN is not equal to the determined
    1600                 :            :    length or if we are unable to determine the length, return false.
    1601                 :            :    VISITED is a bitmap of visited variables.
    1602                 :            :    RKIND determines the kind of value or range to obtain (see
    1603                 :            :    strlen_range_kind).
    1604                 :            :    Set PDATA->DECL if ARG refers to an unterminated constant array.
    1605                 :            :    On input, set ELTSIZE to 1 for normal single byte character strings,
    1606                 :            :    and either 2 or 4 for wide characer strings (the size of wchar_t).
    1607                 :            :    Return true if *PDATA was successfully populated and false otherwise.  */
    1608                 :            : 
    1609                 :            : static bool
    1610                 :     246890 : get_range_strlen (tree arg, bitmap *visited,
    1611                 :            :                   strlen_range_kind rkind,
    1612                 :            :                   c_strlen_data *pdata, unsigned eltsize)
    1613                 :            : {
    1614                 :            : 
    1615                 :     283505 :   if (TREE_CODE (arg) != SSA_NAME)
    1616                 :     160683 :     return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);
    1617                 :            : 
    1618                 :            :   /* If ARG is registered for SSA update we cannot look at its defining
    1619                 :            :      statement.  */
    1620                 :     122822 :   if (name_registered_for_update_p (arg))
    1621                 :            :     return false;
    1622                 :            : 
    1623                 :            :   /* If we were already here, break the infinite cycle.  */
    1624                 :     122822 :   if (!*visited)
    1625                 :     112305 :     *visited = BITMAP_ALLOC (NULL);
    1626                 :     122822 :   if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (arg)))
    1627                 :            :     return true;
    1628                 :            : 
    1629                 :     122118 :   tree var = arg;
    1630                 :     122118 :   gimple *def_stmt = SSA_NAME_DEF_STMT (var);
    1631                 :            : 
    1632                 :     122118 :   switch (gimple_code (def_stmt))
    1633                 :            :     {
    1634                 :      62001 :       case GIMPLE_ASSIGN:
    1635                 :            :         /* The RHS of the statement defining VAR must either have a
    1636                 :            :            constant length or come from another SSA_NAME with a constant
    1637                 :            :            length.  */
    1638                 :      62001 :         if (gimple_assign_single_p (def_stmt)
    1639                 :      26002 :             || gimple_assign_unary_nop_p (def_stmt))
    1640                 :            :           {
    1641                 :      36615 :             tree rhs = gimple_assign_rhs1 (def_stmt);
    1642                 :      36615 :             return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
    1643                 :            :           }
    1644                 :      25386 :         else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
    1645                 :            :           {
    1646                 :        157 :             tree ops[2] = { gimple_assign_rhs2 (def_stmt),
    1647                 :        157 :                             gimple_assign_rhs3 (def_stmt) };
    1648                 :            : 
    1649                 :        471 :             for (unsigned int i = 0; i < 2; i++)
    1650                 :        314 :               if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
    1651                 :            :                 {
    1652                 :         10 :                   if (rkind != SRK_LENRANGE)
    1653                 :            :                     return false;
    1654                 :            :                   /* Set the upper bound to the maximum to prevent
    1655                 :            :                      it from being adjusted in the next iteration but
    1656                 :            :                      leave MINLEN and the more conservative MAXBOUND
    1657                 :            :                      determined so far alone (or leave them null if
    1658                 :            :                      they haven't been set yet).  That the MINLEN is
    1659                 :            :                      in fact zero can be determined from MAXLEN being
    1660                 :            :                      unbounded but the discovered minimum is used for
    1661                 :            :                      diagnostics.  */
    1662                 :         10 :                   pdata->maxlen = build_all_ones_cst (size_type_node);
    1663                 :            :                 }
    1664                 :            :             return true;
    1665                 :            :           }
    1666                 :            :         return false;
    1667                 :            : 
    1668                 :            :       case GIMPLE_PHI:
    1669                 :            :         /* Unless RKIND == SRK_LENRANGE, all arguments of the PHI node
    1670                 :            :            must have a constant length.  */
    1671                 :      24926 :         for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
    1672                 :            :           {
    1673                 :      18514 :             tree arg = gimple_phi_arg (def_stmt, i)->def;
    1674                 :            : 
    1675                 :            :             /* If this PHI has itself as an argument, we cannot
    1676                 :            :                determine the string length of this argument.  However,
    1677                 :            :                if we can find a constant string length for the other
    1678                 :            :                PHI args then we can still be sure that this is a
    1679                 :            :                constant string length.  So be optimistic and just
    1680                 :            :                continue with the next argument.  */
    1681                 :      18514 :             if (arg == gimple_phi_result (def_stmt))
    1682                 :          0 :               continue;
    1683                 :            : 
    1684                 :      18514 :             if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
    1685                 :            :               {
    1686                 :       9138 :                 if (rkind != SRK_LENRANGE)
    1687                 :            :                   return false;
    1688                 :            :                 /* Set the upper bound to the maximum to prevent
    1689                 :            :                    it from being adjusted in the next iteration but
    1690                 :            :                    leave MINLEN and the more conservative MAXBOUND
    1691                 :            :                    determined so far alone (or leave them null if
    1692                 :            :                    they haven't been set yet).  That the MINLEN is
    1693                 :            :                    in fact zero can be determined from MAXLEN being
    1694                 :            :                    unbounded but the discovered minimum is used for
    1695                 :            :                    diagnostics.  */
    1696                 :       6458 :                 pdata->maxlen = build_all_ones_cst (size_type_node);
    1697                 :            :               }
    1698                 :            :           }
    1699                 :            :         return true;
    1700                 :            : 
    1701                 :            :       default:
    1702                 :            :         return false;
    1703                 :            :     }
    1704                 :            : }
    1705                 :            : 
    1706                 :            : /* Try to obtain the range of the lengths of the string(s) referenced
    1707                 :            :    by ARG, or the size of the largest array ARG refers to if the range
    1708                 :            :    of lengths cannot be determined, and store all in *PDATA which must
    1709                 :            :    be zero-initialized on input except PDATA->MAXBOUND may be set to
    1710                 :            :    a non-null tree node other than INTEGER_CST to request to have it
    1711                 :            :    set to the length of the longest string in a PHI.  ELTSIZE is
    1712                 :            :    the expected size of the string element in bytes: 1 for char and
    1713                 :            :    some power of 2 for wide characters.
    1714                 :            :    Return true if the range [PDATA->MINLEN, PDATA->MAXLEN] is suitable
    1715                 :            :    for optimization.  Returning false means that a nonzero PDATA->MINLEN
    1716                 :            :    doesn't reflect the true lower bound of the range when PDATA->MAXLEN
    1717                 :            :    is -1 (in that case, the actual range is indeterminate, i.e.,
    1718                 :            :    [0, PTRDIFF_MAX - 2].  */
    1719                 :            : 
    1720                 :            : bool
    1721                 :     126781 : get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
    1722                 :            : {
    1723                 :     126781 :   bitmap visited = NULL;
    1724                 :     126781 :   tree maxbound = pdata->maxbound;
    1725                 :            : 
    1726                 :     126781 :   if (!get_range_strlen (arg, &visited, SRK_LENRANGE, pdata, eltsize))
    1727                 :            :     {
    1728                 :            :       /* On failure extend the length range to an impossible maximum
    1729                 :            :          (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
    1730                 :            :          members can stay unchanged regardless.  */
    1731                 :      86875 :       pdata->minlen = ssize_int (0);
    1732                 :      86875 :       pdata->maxlen = build_all_ones_cst (size_type_node);
    1733                 :            :     }
    1734                 :      39906 :   else if (!pdata->minlen)
    1735                 :       2325 :     pdata->minlen = ssize_int (0);
    1736                 :            : 
    1737                 :            :   /* If it's unchanged from it initial non-null value, set the conservative
    1738                 :            :      MAXBOUND to SIZE_MAX.  Otherwise leave it null (if it is null).  */
    1739                 :     126781 :   if (maxbound && pdata->maxbound == maxbound)
    1740                 :      11681 :     pdata->maxbound = build_all_ones_cst (size_type_node);
    1741                 :            : 
    1742                 :     126781 :   if (visited)
    1743                 :      83621 :     BITMAP_FREE (visited);
    1744                 :            : 
    1745                 :     126781 :   return !integer_all_onesp (pdata->maxlen);
    1746                 :            : }
    1747                 :            : 
    1748                 :            : /* Return the maximum value for ARG given RKIND (see strlen_range_kind).
    1749                 :            :    For ARG of pointer types, NONSTR indicates if the caller is prepared
    1750                 :            :    to handle unterminated strings.   For integer ARG and when RKIND ==
    1751                 :            :    SRK_INT_VALUE, NONSTR must be null.
    1752                 :            : 
    1753                 :            :    If an unterminated array is discovered and our caller handles
    1754                 :            :    unterminated arrays, then bubble up the offending DECL and
    1755                 :            :    return the maximum size.  Otherwise return NULL.  */
    1756                 :            : 
    1757                 :            : static tree
    1758                 :      65979 : get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
    1759                 :            : {
    1760                 :            :   /* A non-null NONSTR is meaningless when determining the maximum
    1761                 :            :      value of an integer ARG.  */
    1762                 :      65979 :   gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL);
    1763                 :            :   /* ARG must have an integral type when RKIND says so.  */
    1764                 :      85028 :   gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
    1765                 :            : 
    1766                 :      65979 :   bitmap visited = NULL;
    1767                 :            : 
    1768                 :            :   /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
    1769                 :            :      is unbounded.  */
    1770                 :      65979 :   c_strlen_data lendata = { };
    1771                 :      65979 :   if (!get_range_strlen (arg, &visited, rkind, &lendata, /* eltsize = */1))
    1772                 :      43724 :     lendata.maxlen = NULL_TREE;
    1773                 :      22255 :   else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
    1774                 :          0 :     lendata.maxlen = NULL_TREE;
    1775                 :            : 
    1776                 :      65979 :   if (visited)
    1777                 :      28684 :     BITMAP_FREE (visited);
    1778                 :            : 
    1779                 :      65979 :   if (nonstr)
    1780                 :            :     {
    1781                 :            :       /* For callers prepared to handle unterminated arrays set
    1782                 :            :          *NONSTR to point to the declaration of the array and return
    1783                 :            :          the maximum length/size. */
    1784                 :      21631 :       *nonstr = lendata.decl;
    1785                 :      21631 :       return lendata.maxlen;
    1786                 :            :     }
    1787                 :            : 
    1788                 :            :   /* Fail if the constant array isn't nul-terminated.  */
    1789                 :      44348 :   return lendata.decl ? NULL_TREE : lendata.maxlen;
    1790                 :            : }
    1791                 :            : 
    1792                 :            : 
    1793                 :            : /* Fold function call to builtin strcpy with arguments DEST and SRC.
    1794                 :            :    If LEN is not NULL, it represents the length of the string to be
    1795                 :            :    copied.  Return NULL_TREE if no simplification can be made.  */
    1796                 :            : 
    1797                 :            : static bool
    1798                 :      23269 : gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
    1799                 :            :                             tree dest, tree src)
    1800                 :            : {
    1801                 :      23269 :   gimple *stmt = gsi_stmt (*gsi);
    1802                 :      23269 :   location_t loc = gimple_location (stmt);
    1803                 :      23269 :   tree fn;
    1804                 :            : 
    1805                 :            :   /* If SRC and DEST are the same (and not volatile), return DEST.  */
    1806                 :      23269 :   if (operand_equal_p (src, dest, 0))
    1807                 :            :     {
    1808                 :            :       /* Issue -Wrestrict unless the pointers are null (those do
    1809                 :            :          not point to objects and so do not indicate an overlap;
    1810                 :            :          such calls could be the result of sanitization and jump
    1811                 :            :          threading).  */
    1812                 :         67 :       if (!integer_zerop (dest) && !gimple_no_warning_p (stmt))
    1813                 :            :         {
    1814                 :         54 :           tree func = gimple_call_fndecl (stmt);
    1815                 :            : 
    1816                 :         54 :           warning_at (loc, OPT_Wrestrict,
    1817                 :            :                       "%qD source argument is the same as destination",
    1818                 :            :                       func);
    1819                 :            :         }
    1820                 :            : 
    1821                 :         67 :       replace_call_with_value (gsi, dest);
    1822                 :         67 :       return true;
    1823                 :            :     }
    1824                 :            : 
    1825                 :      23202 :   if (optimize_function_for_size_p (cfun))
    1826                 :            :     return false;
    1827                 :            : 
    1828                 :      21631 :   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    1829                 :      21631 :   if (!fn)
    1830                 :            :     return false;
    1831                 :            : 
    1832                 :            :   /* Set to non-null if ARG refers to an unterminated array.  */
    1833                 :      21631 :   tree nonstr = NULL;
    1834                 :      21631 :   tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);
    1835                 :            : 
    1836                 :      21631 :   if (nonstr)
    1837                 :            :     {
    1838                 :            :       /* Avoid folding calls with unterminated arrays.  */
    1839                 :        596 :       if (!gimple_no_warning_p (stmt))
    1840                 :         69 :         warn_string_no_nul (loc, "strcpy", src, nonstr);
    1841                 :        596 :       gimple_set_no_warning (stmt, true);
    1842                 :        596 :       return false;
    1843                 :            :     }
    1844                 :            : 
    1845                 :      21035 :   if (!len)
    1846                 :            :     return false;
    1847                 :            : 
    1848                 :       2446 :   len = fold_convert_loc (loc, size_type_node, len);
    1849                 :       2446 :   len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
    1850                 :       2446 :   len = force_gimple_operand_gsi (gsi, len, true,
    1851                 :            :                                   NULL_TREE, true, GSI_SAME_STMT);
    1852                 :       2446 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    1853                 :       2446 :   replace_call_with_call_and_fold (gsi, repl);
    1854                 :       2446 :   return true;
    1855                 :            : }
    1856                 :            : 
    1857                 :            : /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
    1858                 :            :    If SLEN is not NULL, it represents the length of the source string.
    1859                 :            :    Return NULL_TREE if no simplification can be made.  */
    1860                 :            : 
    1861                 :            : static bool
    1862                 :      18381 : gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
    1863                 :            :                              tree dest, tree src, tree len)
    1864                 :            : {
    1865                 :      18381 :   gimple *stmt = gsi_stmt (*gsi);
    1866                 :      18381 :   location_t loc = gimple_location (stmt);
    1867                 :      18381 :   bool nonstring = get_attr_nonstring_decl (dest) != NULL_TREE;
    1868                 :            : 
    1869                 :            :   /* If the LEN parameter is zero, return DEST.  */
    1870                 :      18381 :   if (integer_zerop (len))
    1871                 :            :     {
    1872                 :            :       /* Avoid warning if the destination refers to an array/pointer
    1873                 :            :          decorate with attribute nonstring.  */
    1874                 :        172 :       if (!nonstring)
    1875                 :            :         {
    1876                 :        167 :           tree fndecl = gimple_call_fndecl (stmt);
    1877                 :            : 
    1878                 :            :           /* Warn about the lack of nul termination: the result is not
    1879                 :            :              a (nul-terminated) string.  */
    1880                 :        167 :           tree slen = get_maxval_strlen (src, SRK_STRLEN);
    1881                 :        167 :           if (slen && !integer_zerop (slen))
    1882                 :         25 :             warning_at (loc, OPT_Wstringop_truncation,
    1883                 :            :                         "%G%qD destination unchanged after copying no bytes "
    1884                 :            :                         "from a string of length %E",
    1885                 :            :                         stmt, fndecl, slen);
    1886                 :            :           else
    1887                 :        142 :             warning_at (loc, OPT_Wstringop_truncation,
    1888                 :            :                         "%G%qD destination unchanged after copying no bytes",
    1889                 :            :                         stmt, fndecl);
    1890                 :            :         }
    1891                 :            : 
    1892                 :        172 :       replace_call_with_value (gsi, dest);
    1893                 :        172 :       return true;
    1894                 :            :     }
    1895                 :            : 
    1896                 :            :   /* We can't compare slen with len as constants below if len is not a
    1897                 :            :      constant.  */
    1898                 :      18209 :   if (TREE_CODE (len) != INTEGER_CST)
    1899                 :            :     return false;
    1900                 :            : 
    1901                 :            :   /* Now, we must be passed a constant src ptr parameter.  */
    1902                 :      11397 :   tree slen = get_maxval_strlen (src, SRK_STRLEN);
    1903                 :      11397 :   if (!slen || TREE_CODE (slen) != INTEGER_CST)
    1904                 :            :     return false;
    1905                 :            : 
    1906                 :            :   /* The size of the source string including the terminating nul.  */
    1907                 :       1986 :   tree ssize = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
    1908                 :            : 
    1909                 :            :   /* We do not support simplification of this case, though we do
    1910                 :            :      support it when expanding trees into RTL.  */
    1911                 :            :   /* FIXME: generate a call to __builtin_memset.  */
    1912                 :       1986 :   if (tree_int_cst_lt (ssize, len))
    1913                 :            :     return false;
    1914                 :            : 
    1915                 :            :   /* Diagnose truncation that leaves the copy unterminated.  */
    1916                 :        725 :   maybe_diag_stxncpy_trunc (*gsi, src, len);
    1917                 :            : 
    1918                 :            :   /* OK transform into builtin memcpy.  */
    1919                 :        725 :   tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    1920                 :        725 :   if (!fn)
    1921                 :            :     return false;
    1922                 :            : 
    1923                 :        725 :   len = fold_convert_loc (loc, size_type_node, len);
    1924                 :        725 :   len = force_gimple_operand_gsi (gsi, len, true,
    1925                 :            :                                   NULL_TREE, true, GSI_SAME_STMT);
    1926                 :        725 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    1927                 :        725 :   replace_call_with_call_and_fold (gsi, repl);
    1928                 :            : 
    1929                 :        725 :   return true;
    1930                 :            : }
    1931                 :            : 
    1932                 :            : /* Fold function call to builtin strchr or strrchr.
    1933                 :            :    If both arguments are constant, evaluate and fold the result,
    1934                 :            :    otherwise simplify str(r)chr (str, 0) into str + strlen (str).
    1935                 :            :    In general strlen is significantly faster than strchr
    1936                 :            :    due to being a simpler operation.  */
    1937                 :            : static bool
    1938                 :       5325 : gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
    1939                 :            : {
    1940                 :       5325 :   gimple *stmt = gsi_stmt (*gsi);
    1941                 :       5325 :   tree str = gimple_call_arg (stmt, 0);
    1942                 :       5325 :   tree c = gimple_call_arg (stmt, 1);
    1943                 :       5325 :   location_t loc = gimple_location (stmt);
    1944                 :       5325 :   const char *p;
    1945                 :       5325 :   char ch;
    1946                 :            : 
    1947                 :       5325 :   if (!gimple_call_lhs (stmt))
    1948                 :            :     return false;
    1949                 :            : 
    1950                 :            :   /* Avoid folding if the first argument is not a nul-terminated array.
    1951                 :            :      Defer warning until later.  */
    1952                 :       5317 :   if (!check_nul_terminated_array (NULL_TREE, str))
    1953                 :            :     return false;
    1954                 :            : 
    1955                 :       5225 :   if ((p = c_getstr (str)) && target_char_cst_p (c, &ch))
    1956                 :            :     {
    1957                 :         49 :       const char *p1 = is_strrchr ? strrchr (p, ch) : strchr (p, ch);
    1958                 :            : 
    1959                 :         49 :       if (p1 == NULL)
    1960                 :            :         {
    1961                 :          1 :           replace_call_with_value (gsi, integer_zero_node);
    1962                 :          1 :           return true;
    1963                 :            :         }
    1964                 :            : 
    1965                 :         48 :       tree len = build_int_cst (size_type_node, p1 - p);
    1966                 :         48 :       gimple_seq stmts = NULL;
    1967                 :         48 :       gimple *new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
    1968                 :            :                                               POINTER_PLUS_EXPR, str, len);
    1969                 :         48 :       gimple_seq_add_stmt_without_update (&stmts, new_stmt);
    1970                 :         48 :       gsi_replace_with_seq_vops (gsi, stmts);
    1971                 :         48 :       return true;
    1972                 :            :     }
    1973                 :            : 
    1974                 :       5176 :   if (!integer_zerop (c))
    1975                 :            :     return false;
    1976                 :            : 
    1977                 :            :   /* Transform strrchr (s, 0) to strchr (s, 0) when optimizing for size.  */
    1978                 :         82 :   if (is_strrchr && optimize_function_for_size_p (cfun))
    1979                 :            :     {
    1980                 :          3 :       tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
    1981                 :            : 
    1982                 :          3 :       if (strchr_fn)
    1983                 :            :         {
    1984                 :          3 :           gimple *repl = gimple_build_call (strchr_fn, 2, str, c);
    1985                 :          3 :           replace_call_with_call_and_fold (gsi, repl);
    1986                 :          3 :           return true;
    1987                 :            :         }
    1988                 :            : 
    1989                 :            :       return false;
    1990                 :            :     }
    1991                 :            : 
    1992                 :         79 :   tree len;
    1993                 :         79 :   tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
    1994                 :            : 
    1995                 :         79 :   if (!strlen_fn)
    1996                 :            :     return false;
    1997                 :            : 
    1998                 :            :   /* Create newstr = strlen (str).  */
    1999                 :         79 :   gimple_seq stmts = NULL;
    2000                 :         79 :   gimple *new_stmt = gimple_build_call (strlen_fn, 1, str);
    2001                 :         79 :   gimple_set_location (new_stmt, loc);
    2002                 :         79 :   len = create_tmp_reg_or_ssa_name (size_type_node);
    2003                 :         79 :   gimple_call_set_lhs (new_stmt, len);
    2004                 :         79 :   gimple_seq_add_stmt_without_update (&stmts, new_stmt);
    2005                 :            : 
    2006                 :            :   /* Create (str p+ strlen (str)).  */
    2007                 :         79 :   new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
    2008                 :            :                                   POINTER_PLUS_EXPR, str, len);
    2009                 :         79 :   gimple_seq_add_stmt_without_update (&stmts, new_stmt);
    2010                 :         79 :   gsi_replace_with_seq_vops (gsi, stmts);
    2011                 :            :   /* gsi now points at the assignment to the lhs, get a
    2012                 :            :      stmt iterator to the strlen.
    2013                 :            :      ???  We can't use gsi_for_stmt as that doesn't work when the
    2014                 :            :      CFG isn't built yet.  */
    2015                 :         79 :   gimple_stmt_iterator gsi2 = *gsi;
    2016                 :         79 :   gsi_prev (&gsi2);
    2017                 :         79 :   fold_stmt (&gsi2);
    2018                 :         79 :   return true;
    2019                 :            : }
    2020                 :            : 
    2021                 :            : /* Fold function call to builtin strstr.
    2022                 :            :    If both arguments are constant, evaluate and fold the result,
    2023                 :            :    additionally fold strstr (x, "") into x and strstr (x, "c")
    2024                 :            :    into strchr (x, 'c').  */
    2025                 :            : static bool
    2026                 :       3000 : gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
    2027                 :            : {
    2028                 :       3000 :   gimple *stmt = gsi_stmt (*gsi);
    2029                 :       3000 :   if (!gimple_call_lhs (stmt))
    2030                 :            :     return false;
    2031                 :            : 
    2032                 :       2997 :   tree haystack = gimple_call_arg (stmt, 0);
    2033                 :       2997 :   tree needle = gimple_call_arg (stmt, 1);
    2034                 :            : 
    2035                 :            :   /* Avoid folding if either argument is not a nul-terminated array.
    2036                 :            :      Defer warning until later.  */
    2037                 :       2997 :   if (!check_nul_terminated_array (NULL_TREE, haystack)
    2038                 :       2997 :       || !check_nul_terminated_array (NULL_TREE, needle))
    2039                 :         19 :     return false;
    2040                 :            : 
    2041                 :       2978 :   const char *q = c_getstr (needle);
    2042                 :       2978 :   if (q == NULL)
    2043                 :            :     return false;
    2044                 :            : 
    2045                 :       2293 :   if (const char *p = c_getstr (haystack))
    2046                 :            :     {
    2047                 :         18 :       const char *r = strstr (p, q);
    2048                 :            : 
    2049                 :         18 :       if (r == NULL)
    2050                 :            :         {
    2051                 :          1 :           replace_call_with_value (gsi, integer_zero_node);
    2052                 :          1 :           return true;
    2053                 :            :         }
    2054                 :            : 
    2055                 :         17 :       tree len = build_int_cst (size_type_node, r - p);
    2056                 :         17 :       gimple_seq stmts = NULL;
    2057                 :         17 :       gimple *new_stmt
    2058                 :         17 :         = gimple_build_assign (gimple_call_lhs (stmt), POINTER_PLUS_EXPR,
    2059                 :            :                                haystack, len);
    2060                 :         17 :       gimple_seq_add_stmt_without_update (&stmts, new_stmt);
    2061                 :         17 :       gsi_replace_with_seq_vops (gsi, stmts);
    2062                 :         17 :       return true;
    2063                 :            :     }
    2064                 :            : 
    2065                 :            :   /* For strstr (x, "") return x.  */
    2066                 :       2275 :   if (q[0] == '\0')
    2067                 :            :     {
    2068                 :          6 :       replace_call_with_value (gsi, haystack);
    2069                 :          6 :       return true;
    2070                 :            :     }
    2071                 :            : 
    2072                 :            :   /* Transform strstr (x, "c") into strchr (x, 'c').  */
    2073                 :       2269 :   if (q[1] == '\0')
    2074                 :            :     {
    2075                 :         21 :       tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
    2076                 :         21 :       if (strchr_fn)
    2077                 :            :         {
    2078                 :         21 :           tree c = build_int_cst (integer_type_node, q[0]);
    2079                 :         21 :           gimple *repl = gimple_build_call (strchr_fn, 2, haystack, c);
    2080                 :         21 :           replace_call_with_call_and_fold (gsi, repl);
    2081                 :         21 :           return true;
    2082                 :            :         }
    2083                 :            :     }
    2084                 :            : 
    2085                 :            :   return false;
    2086                 :            : }
    2087                 :            : 
    2088                 :            : /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
    2089                 :            :    to the call.
    2090                 :            : 
    2091                 :            :    Return NULL_TREE if no simplification was possible, otherwise return the
    2092                 :            :    simplified form of the call as a tree.
    2093                 :            : 
    2094                 :            :    The simplified form may be a constant or other expression which
    2095                 :            :    computes the same value, but in a more efficient manner (including
    2096                 :            :    calls to other builtin functions).
    2097                 :            : 
    2098                 :            :    The call may contain arguments which need to be evaluated, but
    2099                 :            :    which are not useful to determine the result of the call.  In
    2100                 :            :    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
    2101                 :            :    COMPOUND_EXPR will be an argument which must be evaluated.
    2102                 :            :    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
    2103                 :            :    COMPOUND_EXPR in the chain will contain the tree for the simplified
    2104                 :            :    form of the builtin function call.  */
    2105                 :            : 
    2106                 :            : static bool
    2107                 :       7236 : gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
    2108                 :            : {
    2109                 :       7236 :   gimple *stmt = gsi_stmt (*gsi);
    2110                 :       7236 :   location_t loc = gimple_location (stmt);
    2111                 :            : 
    2112                 :       7236 :   const char *p = c_getstr (src);
    2113                 :            : 
    2114                 :            :   /* If the string length is zero, return the dst parameter.  */
    2115                 :       7236 :   if (p && *p == '\0')
    2116                 :            :     {
    2117                 :         66 :       replace_call_with_value (gsi, dst);
    2118                 :         66 :       return true;
    2119                 :            :     }
    2120                 :            : 
    2121                 :       7170 :   if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
    2122                 :            :     return false;
    2123                 :            : 
    2124                 :            :   /* See if we can store by pieces into (dst + strlen(dst)).  */
    2125                 :       6529 :   tree newdst;
    2126                 :       6529 :   tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
    2127                 :       6529 :   tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    2128                 :            : 
    2129                 :       6529 :   if (!strlen_fn || !memcpy_fn)
    2130                 :            :     return false;
    2131                 :            : 
    2132                 :            :   /* If the length of the source string isn't computable don't
    2133                 :            :      split strcat into strlen and memcpy.  */
    2134                 :       6529 :   tree len = get_maxval_strlen (src, SRK_STRLEN);
    2135                 :       6529 :   if (! len)
    2136                 :            :     return false;
    2137                 :            : 
    2138                 :            :   /* Create strlen (dst).  */
    2139                 :        589 :   gimple_seq stmts = NULL, stmts2;
    2140                 :        589 :   gimple *repl = gimple_build_call (strlen_fn, 1, dst);
    2141                 :        589 :   gimple_set_location (repl, loc);
    2142                 :        589 :   newdst = create_tmp_reg_or_ssa_name (size_type_node);
    2143                 :        589 :   gimple_call_set_lhs (repl, newdst);
    2144                 :        589 :   gimple_seq_add_stmt_without_update (&stmts, repl);
    2145                 :            : 
    2146                 :            :   /* Create (dst p+ strlen (dst)).  */
    2147                 :        589 :   newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
    2148                 :        589 :   newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE);
    2149                 :        589 :   gimple_seq_add_seq_without_update (&stmts, stmts2);
    2150                 :            : 
    2151                 :        589 :   len = fold_convert_loc (loc, size_type_node, len);
    2152                 :        589 :   len = size_binop_loc (loc, PLUS_EXPR, len,
    2153                 :        589 :                         build_int_cst (size_type_node, 1));
    2154                 :        589 :   len = force_gimple_operand (len, &stmts2, true, NULL_TREE);
    2155                 :        589 :   gimple_seq_add_seq_without_update (&stmts, stmts2);
    2156                 :            : 
    2157                 :        589 :   repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
    2158                 :        589 :   gimple_seq_add_stmt_without_update (&stmts, repl);
    2159                 :        589 :   if (gimple_call_lhs (stmt))
    2160                 :            :     {
    2161                 :        159 :       repl = gimple_build_assign (gimple_call_lhs (stmt), dst);
    2162                 :        159 :       gimple_seq_add_stmt_without_update (&stmts, repl);
    2163                 :        159 :       gsi_replace_with_seq_vops (gsi, stmts);
    2164                 :            :       /* gsi now points at the assignment to the lhs, get a
    2165                 :            :          stmt iterator to the memcpy call.
    2166                 :            :          ???  We can't use gsi_for_stmt as that doesn't work when the
    2167                 :            :          CFG isn't built yet.  */
    2168                 :        159 :       gimple_stmt_iterator gsi2 = *gsi;
    2169                 :        159 :       gsi_prev (&gsi2);
    2170                 :        159 :       fold_stmt (&gsi2);
    2171                 :            :     }
    2172                 :            :   else
    2173                 :            :     {
    2174                 :        430 :       gsi_replace_with_seq_vops (gsi, stmts);
    2175                 :        430 :       fold_stmt (gsi);
    2176                 :            :     }
    2177                 :            :   return true;
    2178                 :            : }
    2179                 :            : 
    2180                 :            : /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
    2181                 :            :    are the arguments to the call.  */
    2182                 :            : 
    2183                 :            : static bool
    2184                 :       1790 : gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
    2185                 :            : {
    2186                 :       1790 :   gimple *stmt = gsi_stmt (*gsi);
    2187                 :       1790 :   tree dest = gimple_call_arg (stmt, 0);
    2188                 :       1790 :   tree src = gimple_call_arg (stmt, 1);
    2189                 :       1790 :   tree size = gimple_call_arg (stmt, 2);
    2190                 :       1790 :   tree fn;
    2191                 :       1790 :   const char *p;
    2192                 :            : 
    2193                 :            : 
    2194                 :       1790 :   p = c_getstr (src);
    2195                 :            :   /* If the SRC parameter is "", return DEST.  */
    2196                 :       1790 :   if (p && *p == '\0')
    2197                 :            :     {
    2198                 :         60 :       replace_call_with_value (gsi, dest);
    2199                 :         60 :       return true;
    2200                 :            :     }
    2201                 :            : 
    2202                 :       1730 :   if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
    2203                 :       1653 :     return false;
    2204                 :            : 
    2205                 :            :   /* If __builtin_strcat_chk is used, assume strcat is available.  */
    2206                 :         77 :   fn = builtin_decl_explicit (BUILT_IN_STRCAT);
    2207                 :         77 :   if (!fn)
    2208                 :            :     return false;
    2209                 :            : 
    2210                 :         77 :   gimple *repl = gimple_build_call (fn, 2, dest, src);
    2211                 :         77 :   replace_call_with_call_and_fold (gsi, repl);
    2212                 :         77 :   return true;
    2213                 :            : }
    2214                 :            : 
    2215                 :            : /* Simplify a call to the strncat builtin.  */
    2216                 :            : 
    2217                 :            : static bool
    2218                 :       6607 : gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
    2219                 :            : {
    2220                 :       6607 :   gimple *stmt = gsi_stmt (*gsi);
    2221                 :       6607 :   tree dst = gimple_call_arg (stmt, 0);
    2222                 :       6607 :   tree src = gimple_call_arg (stmt, 1);
    2223                 :       6607 :   tree len = gimple_call_arg (stmt, 2);
    2224                 :            : 
    2225                 :       6607 :   const char *p = c_getstr (src);
    2226                 :            : 
    2227                 :            :   /* If the requested length is zero, or the src parameter string
    2228                 :            :      length is zero, return the dst parameter.  */
    2229                 :       6607 :   if (integer_zerop (len) || (p && *p == '\0'))
    2230                 :            :     {
    2231                 :        116 :       replace_call_with_value (gsi, dst);
    2232                 :        116 :       return true;
    2233                 :            :     }
    2234                 :            : 
    2235                 :       6491 :   if (TREE_CODE (len) != INTEGER_CST || !p)
    2236                 :            :     return false;
    2237                 :            : 
    2238                 :        693 :   unsigned srclen = strlen (p);
    2239                 :            : 
    2240                 :        693 :   int cmpsrc = compare_tree_int (len, srclen);
    2241                 :            : 
    2242                 :            :   /* Return early if the requested len is less than the string length.
    2243                 :            :      Warnings will be issued elsewhere later.  */
    2244                 :        693 :   if (cmpsrc < 0)
    2245                 :            :     return false;
    2246                 :            : 
    2247                 :        142 :   unsigned HOST_WIDE_INT dstsize;
    2248                 :            : 
    2249                 :        142 :   bool nowarn = gimple_no_warning_p (stmt);
    2250                 :            : 
    2251                 :        142 :   if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize))
    2252                 :            :     {
    2253                 :         60 :       int cmpdst = compare_tree_int (len, dstsize);
    2254                 :            : 
    2255                 :         60 :       if (cmpdst >= 0)
    2256                 :            :         {
    2257                 :         35 :           tree fndecl = gimple_call_fndecl (stmt);
    2258                 :            : 
    2259                 :            :           /* Strncat copies (at most) LEN bytes and always appends
    2260                 :            :              the terminating NUL so the specified bound should never
    2261                 :            :              be equal to (or greater than) the size of the destination.
    2262                 :            :              If it is, the copy could overflow.  */
    2263                 :         35 :           location_t loc = gimple_location (stmt);
    2264                 :         69 :           nowarn = warning_at (loc, OPT_Wstringop_overflow_,
    2265                 :            :                                cmpdst == 0
    2266                 :            :                                ? G_("%G%qD specified bound %E equals "
    2267                 :            :                                     "destination size")
    2268                 :            :                                : G_("%G%qD specified bound %E exceeds "
    2269                 :            :                                     "destination size %wu"),
    2270                 :            :                                stmt, fndecl, len, dstsize);
    2271                 :         35 :           if (nowarn)
    2272                 :          0 :             gimple_set_no_warning (stmt, true);
    2273                 :            :         }
    2274                 :            :     }
    2275                 :            : 
    2276                 :        142 :   if (!nowarn && cmpsrc == 0)
    2277                 :            :     {
    2278                 :         26 :       tree fndecl = gimple_call_fndecl (stmt);
    2279                 :         26 :       location_t loc = gimple_location (stmt);
    2280                 :            : 
    2281                 :            :       /* To avoid possible overflow the specified bound should also
    2282                 :            :          not be equal to the length of the source, even when the size
    2283                 :            :          of the destination is unknown (it's not an uncommon mistake
    2284                 :            :          to specify as the bound to strncpy the length of the source).  */
    2285                 :         26 :       if (warning_at (loc, OPT_Wstringop_overflow_,
    2286                 :            :                       "%G%qD specified bound %E equals source length",
    2287                 :            :                       stmt, fndecl, len))
    2288                 :         11 :         gimple_set_no_warning (stmt, true);
    2289                 :            :     }
    2290                 :            : 
    2291                 :        142 :   tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
    2292                 :            : 
    2293                 :            :   /* If the replacement _DECL isn't initialized, don't do the
    2294                 :            :      transformation.  */
    2295                 :        142 :   if (!fn)
    2296                 :            :     return false;
    2297                 :            : 
    2298                 :            :   /* Otherwise, emit a call to strcat.  */
    2299                 :        142 :   gcall *repl = gimple_build_call (fn, 2, dst, src);
    2300                 :        142 :   replace_call_with_call_and_fold (gsi, repl);
    2301                 :        142 :   return true;
    2302                 :            : }
    2303                 :            : 
    2304                 :            : /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
    2305                 :            :    LEN, and SIZE.  */
    2306                 :            : 
    2307                 :            : static bool 
    2308                 :       1379 : gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
    2309                 :            : {
    2310                 :       1379 :   gimple *stmt = gsi_stmt (*gsi);
    2311                 :       1379 :   tree dest = gimple_call_arg (stmt, 0);
    2312                 :       1379 :   tree src = gimple_call_arg (stmt, 1);
    2313                 :       1379 :   tree len = gimple_call_arg (stmt, 2);
    2314                 :       1379 :   tree size = gimple_call_arg (stmt, 3);
    2315                 :       1379 :   tree fn;
    2316                 :       1379 :   const char *p;
    2317                 :            : 
    2318                 :       1379 :   p = c_getstr (src);
    2319                 :            :   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
    2320                 :        427 :   if ((p && *p == '\0')
    2321                 :       1755 :       || integer_zerop (len))
    2322                 :            :     {
    2323                 :         78 :       replace_call_with_value (gsi, dest);
    2324                 :         78 :       return true;
    2325                 :            :     }
    2326                 :            : 
    2327                 :       1301 :   if (! tree_fits_uhwi_p (size))
    2328                 :            :     return false;
    2329                 :            : 
    2330                 :        791 :   if (! integer_all_onesp (size))
    2331                 :            :     {
    2332                 :        697 :       tree src_len = c_strlen (src, 1);
    2333                 :        697 :       if (src_len
    2334                 :        144 :           && tree_fits_uhwi_p (src_len)
    2335                 :        144 :           && tree_fits_uhwi_p (len)
    2336                 :        835 :           && ! tree_int_cst_lt (len, src_len))
    2337                 :            :         {
    2338                 :            :           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
    2339                 :         50 :           fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
    2340                 :         50 :           if (!fn)
    2341                 :            :             return false;
    2342                 :            : 
    2343                 :         50 :           gimple *repl = gimple_build_call (fn, 3, dest, src, size);
    2344                 :         50 :           replace_call_with_call_and_fold (gsi, repl);
    2345                 :         50 :           return true;
    2346                 :            :         }
    2347                 :        647 :       return false;
    2348                 :            :     }
    2349                 :            : 
    2350                 :            :   /* If __builtin_strncat_chk is used, assume strncat is available.  */
    2351                 :         94 :   fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
    2352                 :         94 :   if (!fn)
    2353                 :            :     return false;
    2354                 :            : 
    2355                 :         94 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    2356                 :         94 :   replace_call_with_call_and_fold (gsi, repl);
    2357                 :         94 :   return true;
    2358                 :            : }
    2359                 :            : 
    2360                 :            : /* Build and append gimple statements to STMTS that would load a first
    2361                 :            :    character of a memory location identified by STR.  LOC is location
    2362                 :            :    of the statement.  */
    2363                 :            : 
    2364                 :            : static tree
    2365                 :        348 : gimple_load_first_char (location_t loc, tree str, gimple_seq *stmts)
    2366                 :            : {
    2367                 :        348 :   tree var;
    2368                 :            : 
    2369                 :        348 :   tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
    2370                 :        348 :   tree cst_uchar_ptr_node
    2371                 :        348 :     = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
    2372                 :        348 :   tree off0 = build_int_cst (cst_uchar_ptr_node, 0);
    2373                 :            : 
    2374                 :        348 :   tree temp = fold_build2_loc (loc, MEM_REF, cst_uchar_node, str, off0);
    2375                 :        348 :   gassign *stmt = gimple_build_assign (NULL_TREE, temp);
    2376                 :        348 :   var = create_tmp_reg_or_ssa_name (cst_uchar_node, stmt);
    2377                 :            : 
    2378                 :        348 :   gimple_assign_set_lhs (stmt, var);
    2379                 :        348 :   gimple_seq_add_stmt_without_update (stmts, stmt);
    2380                 :            : 
    2381                 :        348 :   return var;
    2382                 :            : }
    2383                 :            : 
    2384                 :            : /* Fold a call to the str{n}{case}cmp builtin pointed by GSI iterator.  */
    2385                 :            : 
    2386                 :            : static bool
    2387                 :      41538 : gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
    2388                 :            : {
    2389                 :      41538 :   gimple *stmt = gsi_stmt (*gsi);
    2390                 :      41538 :   tree callee = gimple_call_fndecl (stmt);
    2391                 :      41538 :   enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
    2392                 :            : 
    2393                 :      41538 :   tree type = integer_type_node;
    2394                 :      41538 :   tree str1 = gimple_call_arg (stmt, 0);
    2395                 :      41538 :   tree str2 = gimple_call_arg (stmt, 1);
    2396                 :      41538 :   tree lhs = gimple_call_lhs (stmt);
    2397                 :            : 
    2398                 :      41538 :   tree bound_node = NULL_TREE;
    2399                 :      41538 :   unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;
    2400                 :            : 
    2401                 :            :   /* Handle strncmp and strncasecmp functions.  */
    2402                 :      41538 :   if (gimple_call_num_args (stmt) == 3)
    2403                 :            :     {
    2404                 :      14658 :       bound_node = gimple_call_arg (stmt, 2);
    2405                 :      14658 :       if (tree_fits_uhwi_p (bound_node))
    2406                 :       9579 :         bound = tree_to_uhwi (bound_node);
    2407                 :            :     }
    2408                 :            : 
    2409                 :            :   /* If the BOUND parameter is zero, return zero.  */
    2410                 :       9579 :   if (bound == 0)
    2411                 :            :     {
    2412                 :          3 :       replace_call_with_value (gsi, integer_zero_node);
    2413                 :          3 :       return true;
    2414                 :            :     }
    2415                 :            : 
    2416                 :            :   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
    2417                 :      41535 :   if (operand_equal_p (str1, str2, 0))
    2418                 :            :     {
    2419                 :         48 :       replace_call_with_value (gsi, integer_zero_node);
    2420                 :         48 :       return true;
    2421                 :            :     }
    2422                 :            : 
    2423                 :            :   /* Initially set to the number of characters, including the terminating
    2424                 :            :      nul if each array has one.   LENx == strnlen (Sx, LENx) implies that
    2425                 :            :      the array Sx is not terminated by a nul.
    2426                 :            :      For nul-terminated strings then adjusted to their length so that
    2427                 :            :      LENx == NULPOSx holds.  */
    2428                 :      41487 :   unsigned HOST_WIDE_INT len1 = HOST_WIDE_INT_MAX, len2 = len1;
    2429                 :      41487 :   const char *p1 = c_getstr (str1, &len1);
    2430                 :      41487 :   const char *p2 = c_getstr (str2, &len2);
    2431                 :            : 
    2432                 :            :   /* The position of the terminating nul character if one exists, otherwise
    2433                 :            :      a value greater than LENx.  */
    2434                 :      41487 :   unsigned HOST_WIDE_INT nulpos1 = HOST_WIDE_INT_MAX, nulpos2 = nulpos1;
    2435                 :            : 
    2436                 :      41487 :   if (p1)
    2437                 :            :     {
    2438                 :       4441 :       size_t n = strnlen (p1, len1);
    2439                 :       4441 :       if (n < len1)
    2440                 :       4326 :         len1 = nulpos1 = n;
    2441                 :            :     }
    2442                 :            : 
    2443                 :      41487 :   if (p2)
    2444                 :            :     {
    2445                 :      23165 :       size_t n = strnlen (p2, len2);
    2446                 :      23165 :       if (n < len2)
    2447                 :      23101 :         len2 = nulpos2 = n;
    2448                 :            :     }
    2449                 :            : 
    2450                 :            :   /* For known strings, return an immediate value.  */
    2451                 :      41487 :   if (p1 && p2)
    2452                 :            :     {
    2453                 :       1255 :       int r = 0;
    2454                 :       1255 :       bool known_result = false;
    2455                 :            : 
    2456                 :       1255 :       switch (fcode)
    2457                 :            :         {
    2458                 :         55 :         case BUILT_IN_STRCMP:
    2459                 :         55 :         case BUILT_IN_STRCMP_EQ:
    2460                 :         55 :           if (len1 != nulpos1 || len2 != nulpos2)
    2461                 :            :             break;
    2462                 :            : 
    2463                 :         27 :           r = strcmp (p1, p2);
    2464                 :         27 :           known_result = true;
    2465                 :         27 :           break;
    2466                 :            : 
    2467                 :       1119 :         case BUILT_IN_STRNCMP:
    2468                 :       1119 :         case BUILT_IN_STRNCMP_EQ:
    2469                 :       1119 :           {
    2470                 :       1119 :             if (bound == HOST_WIDE_INT_M1U)
    2471                 :            :               break;
    2472                 :            : 
    2473                 :            :             /* Reduce the bound to be no more than the length
    2474                 :            :                of the shorter of the two strings, or the sizes
    2475                 :            :                of the unterminated arrays.  */
    2476                 :         38 :             unsigned HOST_WIDE_INT n = bound;
    2477                 :            : 
    2478                 :         38 :             if (len1 == nulpos1 && len1 < n)
    2479                 :          4 :               n = len1 + 1;
    2480                 :         38 :             if (len2 == nulpos2 && len2 < n)
    2481                 :         11 :               n = len2 + 1;
    2482                 :            : 
    2483                 :         38 :             if (MIN (nulpos1, nulpos2) + 1 < n)
    2484                 :            :               break;
    2485                 :            : 
    2486                 :         38 :             r = strncmp (p1, p2, n);
    2487                 :         38 :             known_result = true;
    2488                 :         38 :             break;
    2489                 :            :           }
    2490                 :            :         /* Only handleable situation is where the string are equal (result 0),
    2491                 :            :            which is already handled by operand_equal_p case.  */
    2492                 :            :         case BUILT_IN_STRCASECMP:
    2493                 :            :           break;
    2494                 :         41 :         case BUILT_IN_STRNCASECMP:
    2495                 :         41 :           {
    2496                 :         41 :             if (bound == HOST_WIDE_INT_M1U)
    2497                 :            :               break;
    2498                 :         41 :             r = strncmp (p1, p2, bound);
    2499                 :         41 :             if (r == 0)
    2500                 :            :               known_result = true;
    2501                 :            :             break;
    2502                 :            :           }
    2503                 :          0 :         default:
    2504                 :          0 :           gcc_unreachable ();
    2505                 :            :         }
    2506                 :            : 
    2507                 :         65 :       if (known_result)
    2508                 :            :         {
    2509                 :         65 :           replace_call_with_value (gsi, build_cmp_result (type, r));
    2510                 :         65 :           return true;
    2511                 :            :         }
    2512                 :            :     }
    2513                 :            : 
    2514                 :      82844 :   bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U)
    2515                 :      31988 :     || fcode == BUILT_IN_STRCMP
    2516                 :      31988 :     || fcode == BUILT_IN_STRCMP_EQ
    2517                 :      46686 :     || fcode == BUILT_IN_STRCASECMP;
    2518                 :            : 
    2519                 :      41422 :   location_t loc = gimple_location (stmt);
    2520                 :            : 
    2521                 :            :   /* If the second arg is "", return *(const unsigned char*)arg1.  */
    2522                 :      41422 :   if (p2 && *p2 == '\0' && nonzero_bound)
    2523                 :            :     {
    2524                 :        139 :       gimple_seq stmts = NULL;
    2525                 :        139 :       tree var = gimple_load_first_char (loc, str1, &stmts);
    2526                 :        139 :       if (lhs)
    2527                 :            :         {
    2528                 :        139 :           stmt = gimple_build_assign (lhs, NOP_EXPR, var);
    2529                 :        139 :           gimple_seq_add_stmt_without_update (&stmts, stmt);
    2530                 :            :         }
    2531                 :            : 
    2532                 :        139 :       gsi_replace_with_seq_vops (gsi, stmts);
    2533                 :        139 :       return true;
    2534                 :            :     }
    2535                 :            : 
    2536                 :            :   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
    2537                 :      41283 :   if (p1 && *p1 == '\0' && nonzero_bound)
    2538                 :            :     {
    2539                 :         85 :       gimple_seq stmts = NULL;
    2540                 :         85 :       tree var = gimple_load_first_char (loc, str2, &stmts);
    2541                 :            : 
    2542                 :         85 :       if (lhs)
    2543                 :            :         {
    2544                 :         85 :           tree c = create_tmp_reg_or_ssa_name (integer_type_node);
    2545                 :         85 :           stmt = gimple_build_assign (c, NOP_EXPR, var);
    2546                 :         85 :           gimple_seq_add_stmt_without_update (&stmts, stmt);
    2547                 :            : 
    2548                 :         85 :           stmt = gimple_build_assign (lhs, NEGATE_EXPR, c);
    2549                 :         85 :           gimple_seq_add_stmt_without_update (&stmts, stmt);
    2550                 :            :         }
    2551                 :            : 
    2552                 :         85 :       gsi_replace_with_seq_vops (gsi, stmts);
    2553                 :         85 :       return true;
    2554                 :            :     }
    2555                 :            : 
    2556                 :            :   /* If BOUND is one, return an expression corresponding to
    2557                 :            :      (*(const unsigned char*)arg2 - *(const unsigned char*)arg1).  */
    2558                 :      41198 :   if (fcode == BUILT_IN_STRNCMP && bound == 1)
    2559                 :            :     {
    2560                 :         62 :       gimple_seq stmts = NULL;
    2561                 :         62 :       tree temp1 = gimple_load_first_char (loc, str1, &stmts);
    2562                 :         62 :       tree temp2 = gimple_load_first_char (loc, str2, &stmts);
    2563                 :            : 
    2564                 :         62 :       if (lhs)
    2565                 :            :         {
    2566                 :         59 :           tree c1 = create_tmp_reg_or_ssa_name (integer_type_node);
    2567                 :         59 :           gassign *convert1 = gimple_build_assign (c1, NOP_EXPR, temp1);
    2568                 :         59 :           gimple_seq_add_stmt_without_update (&stmts, convert1);
    2569                 :            : 
    2570                 :         59 :           tree c2 = create_tmp_reg_or_ssa_name (integer_type_node);
    2571                 :         59 :           gassign *convert2 = gimple_build_assign (c2, NOP_EXPR, temp2);
    2572                 :         59 :           gimple_seq_add_stmt_without_update (&stmts, convert2);
    2573                 :            : 
    2574                 :         59 :           stmt = gimple_build_assign (lhs, MINUS_EXPR, c1, c2);
    2575                 :         59 :           gimple_seq_add_stmt_without_update (&stmts, stmt);
    2576                 :            :         }
    2577                 :            : 
    2578                 :         62 :       gsi_replace_with_seq_vops (gsi, stmts);
    2579                 :         62 :       return true;
    2580                 :            :     }
    2581                 :            : 
    2582                 :            :   /* If BOUND is greater than the length of one constant string,
    2583                 :            :      and the other argument is also a nul-terminated string, replace
    2584                 :            :      strncmp with strcmp.  */
    2585                 :      41136 :   if (fcode == BUILT_IN_STRNCMP
    2586                 :      41136 :       && bound > 0 && bound < HOST_WIDE_INT_M1U
    2587                 :       6651 :       && ((p2 && len2 < bound && len2 == nulpos2)
    2588                 :       6450 :           || (p1 && len1 < bound && len1 == nulpos1)))
    2589                 :            :     {
    2590                 :        266 :       tree fn = builtin_decl_implicit (BUILT_IN_STRCMP);
    2591                 :        266 :       if (!fn)
    2592                 :            :         return false;
    2593                 :        266 :       gimple *repl = gimple_build_call (fn, 2, str1, str2);
    2594                 :        266 :       replace_call_with_call_and_fold (gsi, repl);
    2595                 :        266 :       return true;
    2596                 :            :     }
    2597                 :            : 
    2598                 :            :   return false;
    2599                 :            : }
    2600                 :            : 
    2601                 :            : /* Fold a call to the memchr pointed by GSI iterator.  */
    2602                 :            : 
    2603                 :            : static bool
    2604                 :       6228 : gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
    2605                 :            : {
    2606                 :       6228 :   gimple *stmt = gsi_stmt (*gsi);
    2607                 :       6228 :   tree lhs = gimple_call_lhs (stmt);
    2608                 :       6228 :   tree arg1 = gimple_call_arg (stmt, 0);
    2609                 :       6228 :   tree arg2 = gimple_call_arg (stmt, 1);
    2610                 :       6228 :   tree len = gimple_call_arg (stmt, 2);
    2611                 :            : 
    2612                 :            :   /* If the LEN parameter is zero, return zero.  */
    2613                 :       6228 :   if (integer_zerop (len))
    2614                 :            :     {
    2615                 :          1 :       replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
    2616                 :          1 :       return true;
    2617                 :            :     }
    2618                 :            : 
    2619                 :       6227 :   char c;
    2620                 :       6227 :   if (TREE_CODE (arg2) != INTEGER_CST
    2621                 :       2950 :       || !tree_fits_uhwi_p (len)
    2622                 :       7223 :       || !target_char_cst_p (arg2, &c))
    2623                 :       5231 :     return false;
    2624                 :            : 
    2625                 :        996 :   unsigned HOST_WIDE_INT length = tree_to_uhwi (len);
    2626                 :        996 :   unsigned HOST_WIDE_INT string_length;
    2627                 :        996 :   const char *p1 = c_getstr (arg1, &string_length);
    2628                 :            : 
    2629                 :        996 :   if (p1)
    2630                 :            :     {
    2631                 :        303 :       const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
    2632                 :        303 :       if (r == NULL)
    2633                 :            :         {
    2634                 :        248 :           tree mem_size, offset_node;
    2635                 :        248 :           string_constant (arg1, &offset_node, &mem_size, NULL);
    2636                 :        496 :           unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
    2637                 :        248 :                                           ? 0 : tree_to_uhwi (offset_node);
    2638                 :            :           /* MEM_SIZE is the size of the array the string literal
    2639                 :            :              is stored in.  */
    2640                 :        248 :           unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
    2641                 :        248 :           gcc_checking_assert (string_length <= string_size);
    2642                 :        248 :           if (length <= string_size)
    2643                 :            :             {
    2644                 :          4 :               replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
    2645                 :          4 :               return true;
    2646                 :            :             }
    2647                 :            :         }
    2648                 :            :       else
    2649                 :            :         {
    2650                 :         55 :           unsigned HOST_WIDE_INT offset = r - p1;
    2651                 :         55 :           gimple_seq stmts = NULL;
    2652                 :         55 :           if (lhs != NULL_TREE)
    2653                 :            :             {
    2654                 :         54 :               tree offset_cst = build_int_cst (TREE_TYPE (len), offset);
    2655                 :         54 :               gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
    2656                 :            :                                                    arg1, offset_cst);
    2657                 :         54 :               gimple_seq_add_stmt_without_update (&stmts, stmt);
    2658                 :            :             }
    2659                 :            :           else
    2660                 :          1 :             gimple_seq_add_stmt_without_update (&stmts,
    2661                 :            :                                                 gimple_build_nop ());
    2662                 :            : 
    2663                 :         55 :           gsi_replace_with_seq_vops (gsi, stmts);
    2664                 :         55 :           return true;
    2665                 :            :         }
    2666                 :            :     }
    2667                 :            : 
    2668                 :            :   return false;
    2669                 :            : }
    2670                 :            : 
    2671                 :            : /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
    2672                 :            :    to the call.  IGNORE is true if the value returned
    2673                 :            :    by the builtin will be ignored.  UNLOCKED is true is true if this
    2674                 :            :    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
    2675                 :            :    the known length of the string.  Return NULL_TREE if no simplification
    2676                 :            :    was possible.  */
    2677                 :            : 
    2678                 :            : static bool
    2679                 :       5052 : gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
    2680                 :            :                            tree arg0, tree arg1,
    2681                 :            :                            bool unlocked)
    2682                 :            : {
    2683                 :       5052 :   gimple *stmt = gsi_stmt (*gsi);
    2684                 :            : 
    2685                 :            :   /* If we're using an unlocked function, assume the other unlocked
    2686                 :            :      functions exist explicitly.  */
    2687                 :       5052 :   tree const fn_fputc = (unlocked
    2688                 :       5052 :                          ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
    2689                 :       5052 :                          : builtin_decl_implicit (BUILT_IN_FPUTC));
    2690                 :       5052 :   tree const fn_fwrite = (unlocked
    2691                 :       5052 :                           ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
    2692                 :       5052 :                           : builtin_decl_implicit (BUILT_IN_FWRITE));
    2693                 :            : 
    2694                 :            :   /* If the return value is used, don't do the transformation.  */
    2695                 :       5052 :   if (gimple_call_lhs (stmt))
    2696                 :            :     return false;
    2697                 :            : 
    2698                 :            :   /* Get the length of the string passed to fputs.  If the length
    2699                 :            :      can't be determined, punt.  */
    2700                 :       4973 :   tree len = get_maxval_strlen (arg0, SRK_STRLEN);
    2701                 :       4973 :   if (!len
    2702                 :       3770 :       || TREE_CODE (len) != INTEGER_CST)
    2703                 :            :     return false;
    2704                 :            : 
    2705                 :       3770 :   switch (compare_tree_int (len, 1))
    2706                 :            :     {
    2707                 :         91 :     case -1: /* length is 0, delete the call entirely .  */
    2708                 :         91 :       replace_call_with_value (gsi, integer_zero_node);
    2709                 :         91 :       return true;
    2710                 :            : 
    2711                 :        261 :     case 0: /* length is 1, call fputc.  */
    2712                 :        261 :       {
    2713                 :        261 :         const char *p = c_getstr (arg0);
    2714                 :        261 :         if (p != NULL)
    2715                 :            :           {
    2716                 :        246 :             if (!fn_fputc)
    2717                 :            :               return false;
    2718                 :            : 
    2719                 :        246 :             gimple *repl = gimple_build_call (fn_fputc, 2,
    2720                 :            :                                              build_int_cst
    2721                 :            :                                              (integer_type_node, p[0]), arg1);
    2722                 :        246 :             replace_call_with_call_and_fold (gsi, repl);
    2723                 :        246 :             return true;
    2724                 :            :           }
    2725                 :            :       }
    2726                 :            :       /* FALLTHROUGH */
    2727                 :       3433 :     case 1: /* length is greater than 1, call fwrite.  */
    2728                 :       3433 :       {
    2729                 :            :         /* If optimizing for size keep fputs.  */
    2730                 :       3433 :         if (optimize_function_for_size_p (cfun))
    2731                 :            :           return false;
    2732                 :            :         /* New argument list transforming fputs(string, stream) to
    2733                 :            :            fwrite(string, 1, len, stream).  */
    2734                 :       2825 :         if (!fn_fwrite)
    2735                 :            :           return false;
    2736                 :            : 
    2737                 :       2825 :         gimple *repl = gimple_build_call (fn_fwrite, 4, arg0,
    2738                 :            :                                          size_one_node, len, arg1);
    2739                 :       2825 :         replace_call_with_call_and_fold (gsi, repl);
    2740                 :       2825 :         return true;
    2741                 :            :       }
    2742                 :          0 :     default:
    2743                 :          0 :       gcc_unreachable ();
    2744                 :            :     }
    2745                 :            :   return false;
    2746                 :            : }
    2747                 :            : 
    2748                 :            : /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
    2749                 :            :    DEST, SRC, LEN, and SIZE are the arguments to the call.
    2750                 :            :    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
    2751                 :            :    code of the builtin.  If MAXLEN is not NULL, it is maximum length
    2752                 :            :    passed as third argument.  */
    2753                 :            : 
    2754                 :            : static bool
    2755                 :      29539 : gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
    2756                 :            :                                 tree dest, tree src, tree len, tree size,
    2757                 :            :                                 enum built_in_function fcode)
    2758                 :            : {
    2759                 :      29539 :   gimple *stmt = gsi_stmt (*gsi);
    2760                 :      29539 :   location_t loc = gimple_location (stmt);
    2761                 :      29539 :   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    2762                 :      29539 :   tree fn;
    2763                 :            : 
    2764                 :            :   /* If SRC and DEST are the same (and not volatile), return DEST
    2765                 :            :      (resp. DEST+LEN for __mempcpy_chk).  */
    2766                 :      29539 :   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
    2767                 :            :     {
    2768                 :         13 :       if (fcode != BUILT_IN_MEMPCPY_CHK)
    2769                 :            :         {
    2770                 :          7 :           replace_call_with_value (gsi, dest);
    2771                 :          7 :           return true;
    2772                 :            :         }
    2773                 :            :       else
    2774                 :            :         {
    2775                 :          6 :           gimple_seq stmts = NULL;
    2776                 :          6 :           len = gimple_convert_to_ptrofftype (&stmts, loc, len);
    2777                 :          6 :           tree temp = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
    2778                 :          6 :                                     TREE_TYPE (dest), dest, len);
    2779                 :          6 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    2780                 :          6 :           replace_call_with_value (gsi, temp);
    2781                 :          6 :           return true;
    2782                 :            :         }
    2783                 :            :     }
    2784                 :            : 
    2785                 :      29526 :   if (! tree_fits_uhwi_p (size))
    2786                 :            :     return false;
    2787                 :            : 
    2788                 :      15235 :   tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
    2789                 :      15235 :   if (! integer_all_onesp (size))
    2790                 :            :     {
    2791                 :      13676 :       if (! tree_fits_uhwi_p (len))
    2792                 :            :         {
    2793                 :            :           /* If LEN is not constant, try MAXLEN too.
    2794                 :            :              For MAXLEN only allow optimizing into non-_ocs function
    2795                 :            :              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
    2796                 :       4416 :           if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
    2797                 :            :             {
    2798                 :       4339 :               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
    2799                 :            :                 {
    2800                 :            :                   /* (void) __mempcpy_chk () can be optimized into
    2801                 :            :                      (void) __memcpy_chk ().  */
    2802                 :         22 :                   fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
    2803                 :         22 :                   if (!fn)
    2804                 :            :                     return false;
    2805                 :            : 
    2806                 :         22 :                   gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
    2807                 :         22 :                   replace_call_with_call_and_fold (gsi, repl);
    2808                 :         22 :                   return true;
    2809                 :            :                 }
    2810                 :            :               return false;
    2811                 :            :             }
    2812                 :            :         }
    2813                 :            :       else
    2814                 :            :         maxlen = len;
    2815                 :            : 
    2816                 :       9337 :       if (tree_int_cst_lt (size, maxlen))
    2817                 :            :         return false;
    2818                 :            :     }
    2819                 :            : 
    2820                 :       8461 :   fn = NULL_TREE;
    2821                 :            :   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
    2822                 :            :      mem{cpy,pcpy,move,set} is available.  */
    2823                 :       8461 :   switch (fcode)
    2824                 :            :     {
    2825                 :       1738 :     case BUILT_IN_MEMCPY_CHK:
    2826                 :       1738 :       fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
    2827                 :       1738 :       break;
    2828                 :       1080 :     case BUILT_IN_MEMPCPY_CHK:
    2829                 :       1080 :       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
    2830                 :       1080 :       break;
    2831                 :       1715 :     case BUILT_IN_MEMMOVE_CHK:
    2832                 :       1715 :       fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
    2833                 :       1715 :       break;
    2834                 :       3928 :     case BUILT_IN_MEMSET_CHK:
    2835                 :       3928 :       fn = builtin_decl_explicit (BUILT_IN_MEMSET);
    2836                 :       3928 :       break;
    2837                 :            :     default:
    2838                 :            :       break;
    2839                 :            :     }
    2840                 :            : 
    2841                 :       8461 :   if (!fn)
    2842                 :            :     return false;
    2843                 :            : 
    2844                 :       8461 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    2845                 :       8461 :   replace_call_with_call_and_fold (gsi, repl);
    2846                 :       8461 :   return true;
    2847                 :            : }
    2848                 :            : 
    2849                 :            : /* Fold a call to the __st[rp]cpy_chk builtin.
    2850                 :            :    DEST, SRC, and SIZE are the arguments to the call.
    2851                 :            :    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
    2852                 :            :    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
    2853                 :            :    strings passed as second argument.  */
    2854                 :            : 
    2855                 :            : static bool
    2856                 :       3119 : gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
    2857                 :            :                                 tree dest,
    2858                 :            :                                 tree src, tree size,
    2859                 :            :                                 enum built_in_function fcode)
    2860                 :            : {
    2861                 :       3119 :   gimple *stmt = gsi_stmt (*gsi);
    2862                 :       3119 :   location_t loc = gimple_location (stmt);
    2863                 :       3119 :   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    2864                 :       3119 :   tree len, fn;
    2865                 :            : 
    2866                 :            :   /* If SRC and DEST are the same (and not volatile), return DEST.  */
    2867                 :       3119 :   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
    2868                 :            :     {
    2869                 :            :       /* Issue -Wrestrict unless the pointers are null (those do
    2870                 :            :          not point to objects and so do not indicate an overlap;
    2871                 :            :          such calls could be the result of sanitization and jump
    2872                 :            :          threading).  */
    2873                 :          0 :       if (!integer_zerop (dest) && !gimple_no_warning_p (stmt))
    2874                 :            :         {
    2875                 :          0 :           tree func = gimple_call_fndecl (stmt);
    2876                 :            : 
    2877                 :          0 :           warning_at (loc, OPT_Wrestrict,
    2878                 :            :                       "%qD source argument is the same as destination",
    2879                 :            :                       func);
    2880                 :            :         }
    2881                 :            : 
    2882                 :          0 :       replace_call_with_value (gsi, dest);
    2883                 :          0 :       return true;
    2884                 :            :     }
    2885                 :            : 
    2886                 :       3119 :   if (! tree_fits_uhwi_p (size))
    2887                 :            :     return false;
    2888                 :            : 
    2889                 :       2040 :   tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
    2890                 :       2040 :   if (! integer_all_onesp (size))
    2891                 :            :     {
    2892                 :       1951 :       len = c_strlen (src, 1);
    2893                 :       1951 :       if (! len || ! tree_fits_uhwi_p (len))
    2894                 :            :         {
    2895                 :            :           /* If LEN is not constant, try MAXLEN too.
    2896                 :            :              For MAXLEN only allow optimizing into non-_ocs function
    2897                 :            :              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
    2898                 :       1336 :           if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
    2899                 :            :             {
    2900                 :       1318 :               if (fcode == BUILT_IN_STPCPY_CHK)
    2901                 :            :                 {
    2902                 :        599 :                   if (! ignore)
    2903                 :            :                     return false;
    2904                 :            : 
    2905                 :            :                   /* If return value of __stpcpy_chk is ignored,
    2906                 :            :                      optimize into __strcpy_chk.  */
    2907                 :         18 :                   fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
    2908                 :         18 :                   if (!fn)
    2909                 :            :                     return false;
    2910                 :            : 
    2911                 :         18 :                   gimple *repl = gimple_build_call (fn, 3, dest, src, size);
    2912                 :         18 :                   replace_call_with_call_and_fold (gsi, repl);
    2913                 :         18 :                   return true;
    2914                 :            :                 }
    2915                 :            : 
    2916                 :        720 :               if (! len || TREE_SIDE_EFFECTS (len))
    2917                 :            :                 return false;
    2918                 :            : 
    2919                 :            :               /* If c_strlen returned something, but not a constant,
    2920                 :            :                  transform __strcpy_chk into __memcpy_chk.  */
    2921                 :          1 :               fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
    2922                 :          1 :               if (!fn)
    2923                 :            :                 return false;
    2924                 :            : 
    2925                 :          1 :               gimple_seq stmts = NULL;
    2926                 :          1 :               len = force_gimple_operand (len, &stmts, true, NULL_TREE);
    2927                 :          1 :               len = gimple_convert (&stmts, loc, size_type_node, len);
    2928                 :          1 :               len = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node, len,
    2929                 :          1 :                                   build_int_cst (size_type_node, 1));
    2930                 :          1 :               gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    2931                 :          1 :               gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
    2932                 :          1 :               replace_call_with_call_and_fold (gsi, repl);
    2933                 :          1 :               return true;
    2934                 :            :             }
    2935                 :            :         }
    2936                 :            :       else
    2937                 :            :         maxlen = len;
    2938                 :            : 
    2939                 :        633 :       if (! tree_int_cst_lt (maxlen, size))
    2940                 :            :         return false;
    2941                 :            :     }
    2942                 :            : 
    2943                 :            :   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
    2944                 :        498 :   fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
    2945                 :            :                               ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
    2946                 :        498 :   if (!fn)
    2947                 :            :     return false;
    2948                 :            : 
    2949                 :        498 :   gimple *repl = gimple_build_call (fn, 2, dest, src);
    2950                 :        498 :   replace_call_with_call_and_fold (gsi, repl);
    2951                 :        498 :   return true;
    2952                 :            : }
    2953                 :            : 
    2954                 :            : /* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
    2955                 :            :    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
    2956                 :            :    length passed as third argument. IGNORE is true if return value can be
    2957                 :            :    ignored. FCODE is the BUILT_IN_* code of the builtin. */
    2958                 :            : 
    2959                 :            : static bool
    2960                 :       3280 : gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
    2961                 :            :                                  tree dest, tree src,
    2962                 :            :                                  tree len, tree size,
    2963                 :            :                                  enum built_in_function fcode)
    2964                 :            : {
    2965                 :       3280 :   gimple *stmt = gsi_stmt (*gsi);
    2966                 :       3280 :   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    2967                 :       3280 :   tree fn;
    2968                 :            : 
    2969                 :       3280 :   if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
    2970                 :            :     {
    2971                 :            :        /* If return value of __stpncpy_chk is ignored,
    2972                 :            :           optimize into __strncpy_chk.  */
    2973                 :        225 :        fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
    2974                 :        225 :        if (fn)
    2975                 :            :          {
    2976                 :        225 :            gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
    2977                 :        225 :            replace_call_with_call_and_fold (gsi, repl);
    2978                 :        225 :            return true;
    2979                 :            :          }
    2980                 :            :     }
    2981                 :            : 
    2982                 :       3055 :   if (! tree_fits_uhwi_p (size))
    2983                 :            :     return false;
    2984                 :            : 
    2985                 :       1718 :   tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
    2986                 :       1718 :   if (! integer_all_onesp (size))
    2987                 :            :     {
    2988                 :       1563 :       if (! tree_fits_uhwi_p (len))
    2989                 :            :         {
    2990                 :            :           /* If LEN is not constant, try MAXLEN too.
    2991                 :            :              For MAXLEN only allow optimizing into non-_ocs function
    2992                 :            :              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
    2993                 :        976 :           if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
    2994                 :            :             return false;
    2995                 :            :         }
    2996                 :            :       else
    2997                 :            :         maxlen = len;
    2998                 :            : 
    2999                 :        635 :       if (tree_int_cst_lt (size, maxlen))
    3000                 :            :         return false;
    3001                 :            :     }
    3002                 :            : 
    3003                 :            :   /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
    3004                 :        459 :   fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
    3005                 :            :                               ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
    3006                 :        459 :   if (!fn)
    3007                 :            :     return false;
    3008                 :            : 
    3009                 :        459 :   gimple *repl = gimple_build_call (fn, 3, dest, src, len);
    3010                 :        459 :   replace_call_with_call_and_fold (gsi, repl);
    3011                 :        459 :   return true;
    3012                 :            : }
    3013                 :            : 
    3014                 :            : /* Fold function call to builtin stpcpy with arguments DEST and SRC.
    3015                 :            :    Return NULL_TREE if no simplification can be made.  */
    3016                 :            : 
    3017                 :            : static bool
    3018                 :       4063 : gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
    3019                 :            : {
    3020                 :       4063 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3021                 :       4063 :   location_t loc = gimple_location (stmt);
    3022                 :       4063 :   tree dest = gimple_call_arg (stmt, 0);
    3023                 :       4063 :   tree src = gimple_call_arg (stmt, 1);
    3024                 :       4063 :   tree fn, lenp1;
    3025                 :            : 
    3026                 :            :   /* If the result is unused, replace stpcpy with strcpy.  */
    3027                 :       4063 :   if (gimple_call_lhs (stmt) == NULL_TREE)
    3028                 :            :     {
    3029                 :         48 :       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
    3030                 :         48 :       if (!fn)
    3031                 :            :         return false;
    3032                 :         48 :       gimple_call_set_fndecl (stmt, fn);
    3033                 :         48 :       fold_stmt (gsi);
    3034                 :         48 :       return true;
    3035                 :            :     }
    3036                 :            : 
    3037                 :            :   /* Set to non-null if ARG refers to an unterminated array.  */
    3038                 :       4015 :   c_strlen_data data = { };
    3039                 :       4015 :   tree len = c_strlen (src, 1, &data, 1);
    3040                 :       4015 :   if (!len
    3041                 :        752 :       || TREE_CODE (len) != INTEGER_CST)
    3042                 :            :     {
    3043                 :       3523 :       data.decl = unterminated_array (src);
    3044                 :       3523 :       if (!data.decl)
    3045                 :            :         return false;
    3046                 :            :     }
    3047                 :            : 
    3048                 :       1166 :   if (data.decl)
    3049                 :            :     {
    3050                 :            :       /* Avoid folding calls with unterminated arrays.  */
    3051                 :        674 :       if (!gimple_no_warning_p (stmt))
    3052                 :         74 :         warn_string_no_nul (loc, "stpcpy", src, data.decl);
    3053                 :        674 :       gimple_set_no_warning (stmt, true);
    3054                 :        674 :       return false;
    3055                 :            :     }
    3056                 :            : 
    3057                 :        492 :   if (optimize_function_for_size_p (cfun)
    3058                 :            :       /* If length is zero it's small enough.  */
    3059                 :        492 :       && !integer_zerop (len))
    3060                 :            :     return false;
    3061                 :            : 
    3062                 :            :   /* If the source has a known length replace stpcpy with memcpy.  */
    3063                 :        290 :   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
    3064                 :        290 :   if (!fn)
    3065                 :            :     return false;
    3066                 :            : 
    3067                 :        290 :   gimple_seq stmts = NULL;
    3068                 :        290 :   tree tem = gimple_convert (&stmts, loc, size_type_node, len);
    3069                 :        290 :   lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
    3070                 :        290 :                         tem, build_int_cst (size_type_node, 1));
    3071                 :        290 :   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    3072                 :        290 :   gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
    3073                 :        290 :   gimple_move_vops (repl, stmt);
    3074                 :        290 :   gsi_insert_before (gsi, repl, GSI_SAME_STMT);
    3075                 :            :   /* Replace the result with dest + len.  */
    3076                 :        290 :   stmts = NULL;
    3077                 :        290 :   tem = gimple_convert (&stmts, loc, sizetype, len);
    3078                 :        290 :   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    3079                 :        290 :   gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
    3080                 :            :                                       POINTER_PLUS_EXPR, dest, tem);
    3081                 :        290 :   gsi_replace (gsi, ret, false);
    3082                 :            :   /* Finally fold the memcpy call.  */
    3083                 :        290 :   gimple_stmt_iterator gsi2 = *gsi;
    3084                 :        290 :   gsi_prev (&gsi2);
    3085                 :        290 :   fold_stmt (&gsi2);
    3086                 :        290 :   return true;
    3087                 :            : }
    3088                 :            : 
    3089                 :            : /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
    3090                 :            :    NULL_TREE if a normal call should be emitted rather than expanding
    3091                 :            :    the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
    3092                 :            :    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
    3093                 :            :    passed as second argument.  */
    3094                 :            : 
    3095                 :            : static bool
    3096                 :       3008 : gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
    3097                 :            :                                   enum built_in_function fcode)
    3098                 :            : {
    3099                 :       3008 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3100                 :       3008 :   tree dest, size, len, fn, fmt, flag;
    3101                 :       3008 :   const char *fmt_str;
    3102                 :            : 
    3103                 :            :   /* Verify the required arguments in the original call.  */
    3104                 :       3008 :   if (gimple_call_num_args (stmt) < 5)
    3105                 :            :     return false;
    3106                 :            : 
    3107                 :       3008 :   dest = gimple_call_arg (stmt, 0);
    3108                 :       3008 :   len = gimple_call_arg (stmt, 1);
    3109                 :       3008 :   flag = gimple_call_arg (stmt, 2);
    3110                 :       3008 :   size = gimple_call_arg (stmt, 3);
    3111                 :       3008 :   fmt = gimple_call_arg (stmt, 4);
    3112                 :            : 
    3113                 :       3008 :   if (! tree_fits_uhwi_p (size))
    3114                 :            :     return false;
    3115                 :            : 
    3116                 :       2135 :   if (! integer_all_onesp (size))
    3117                 :            :     {
    3118                 :       2096 :       tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
    3119                 :       2096 :       if (! tree_fits_uhwi_p (len))
    3120                 :            :         {
    3121                 :            :           /* If LEN is not constant, try MAXLEN too.
    3122                 :            :              For MAXLEN only allow optimizing into non-_ocs function
    3123                 :            :              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
    3124                 :       1423 :           if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
    3125                 :            :             return false;
    3126                 :            :         }
    3127                 :            :       else
    3128                 :            :         maxlen = len;
    3129                 :            : 
    3130                 :        680 :       if (tree_int_cst_lt (size, maxlen))
    3131                 :            :         return false;
    3132                 :            :     }
    3133                 :            : 
    3134                 :        312 :   if (!init_target_chars ())
    3135                 :            :     return false;
    3136                 :            : 
    3137                 :            :   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
    3138                 :            :      or if format doesn't contain % chars or is "%s".  */
    3139                 :        312 :   if (! integer_zerop (flag))
    3140                 :            :     {
    3141                 :         57 :       fmt_str = c_getstr (fmt);
    3142                 :         57 :       if (fmt_str == NULL)
    3143                 :            :         return false;
    3144                 :         57 :       if (strchr (fmt_str, target_percent) != NULL
    3145                 :         56 :           && strcmp (fmt_str, target_percent_s))
    3146                 :            :         return false;
    3147                 :            :     }
    3148                 :            : 
    3149                 :            :   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
    3150                 :            :      available.  */
    3151                 :        257 :   fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
    3152                 :            :                               ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
    3153                 :        257 :   if (!fn)
    3154                 :            :     return false;
    3155                 :            : 
    3156                 :            :   /* Replace the called function and the first 5 argument by 3 retaining
    3157                 :            :      trailing varargs.  */
    3158                 :        257 :   gimple_call_set_fndecl (stmt, fn);
    3159                 :        257 :   gimple_call_set_fntype (stmt, TREE_TYPE (fn));
    3160                 :        257 :   gimple_call_set_arg (stmt, 0, dest);
    3161                 :        257 :   gimple_call_set_arg (stmt, 1, len);
    3162                 :        257 :   gimple_call_set_arg (stmt, 2, fmt);
    3163                 :        542 :   for (unsigned i = 3; i < gimple_call_num_args (stmt) - 2; ++i)
    3164                 :        285 :     gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
    3165                 :        257 :   gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
    3166                 :        257 :   fold_stmt (gsi);
    3167                 :        257 :   return true;
    3168                 :            : }
    3169                 :            : 
    3170                 :            : /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
    3171                 :            :    Return NULL_TREE if a normal call should be emitted rather than
    3172                 :            :    expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
    3173                 :            :    or BUILT_IN_VSPRINTF_CHK.  */
    3174                 :            : 
    3175                 :            : static bool
    3176                 :       5162 : gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
    3177                 :            :                                  enum built_in_function fcode)
    3178                 :            : {
    3179                 :       5162 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3180                 :       5162 :   tree dest, size, len, fn, fmt, flag;
    3181                 :       5162 :   const char *fmt_str;
    3182                 :       5162 :   unsigned nargs = gimple_call_num_args (stmt);
    3183                 :            : 
    3184                 :            :   /* Verify the required arguments in the original call.  */
    3185                 :       5162 :   if (nargs < 4)
    3186                 :            :     return false;
    3187                 :       5162 :   dest = gimple_call_arg (stmt, 0);
    3188                 :       5162 :   flag = gimple_call_arg (stmt, 1);
    3189                 :       5162 :   size = gimple_call_arg (stmt, 2);
    3190                 :       5162 :   fmt = gimple_call_arg (stmt, 3);
    3191                 :            : 
    3192                 :       5162 :   if (! tree_fits_uhwi_p (size))
    3193                 :            :     return false;
    3194                 :            : 
    3195                 :       3757 :   len = NULL_TREE;
    3196                 :            : 
    3197                 :       3757 :   if (!init_target_chars ())
    3198                 :            :     return false;
    3199                 :            : 
    3200                 :            :   /* Check whether the format is a literal string constant.  */
    3201                 :       3757 :   fmt_str = c_getstr (fmt);
    3202                 :       3757 :   if (fmt_str != NULL)
    3203                 :            :     {
    3204                 :            :       /* If the format doesn't contain % args or %%, we know the size.  */
    3205                 :       3523 :       if (strchr (fmt_str, target_percent) == 0)
    3206                 :            :         {
    3207                 :        233 :           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
    3208                 :        233 :             len = build_int_cstu (size_type_node, strlen (fmt_str));
    3209                 :            :         }
    3210                 :            :       /* If the format is "%s" and first ... argument is a string literal,
    3211                 :            :          we know the size too.  */
    3212                 :       3290 :       else if (fcode == BUILT_IN_SPRINTF_CHK
    3213                 :       2505 :                && strcmp (fmt_str, target_percent_s) == 0)
    3214                 :            :         {
    3215                 :        337 :           tree arg;
    3216                 :            : 
    3217                 :        337 :           if (nargs == 5)
    3218                 :            :             {
    3219                 :        337 :               arg = gimple_call_arg (stmt, 4);
    3220                 :        337 :               if (POINTER_TYPE_P (TREE_TYPE (arg)))
    3221                 :            :                 {
    3222                 :        337 :                   len = c_strlen (arg, 1);
    3223                 :        337 :                   if (! len || ! tree_fits_uhwi_p (len))
    3224                 :        212 :                     len = NULL_TREE;
    3225                 :            :                 }
    3226                 :            :             }
    3227                 :            :         }
    3228                 :            :     }
    3229                 :            : 
    3230                 :       3757 :   if (! integer_all_onesp (size))
    3231                 :            :     {
    3232                 :       3667 :       if (! len || ! tree_int_cst_lt (len, size))
    3233                 :       3556 :         return false;
    3234                 :            :     }
    3235                 :            : 
    3236                 :            :   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
    3237                 :            :      or if format doesn't contain % chars or is "%s".  */
    3238                 :        201 :   if (! integer_zerop (flag))
    3239                 :            :     {
    3240                 :          0 :       if (fmt_str == NULL)
    3241                 :            :         return false;
    3242                 :          0 :       if (strchr (fmt_str, target_percent) != NULL
    3243                 :          0 :           && strcmp (fmt_str, target_percent_s))
    3244                 :            :         return false;
    3245                 :            :     }
    3246                 :            : 
    3247                 :            :   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
    3248                 :        201 :   fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
    3249                 :            :                               ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
    3250                 :        201 :   if (!fn)
    3251                 :            :     return false;
    3252                 :            : 
    3253                 :            :   /* Replace the called function and the first 4 argument by 2 retaining
    3254                 :            :      trailing varargs.  */
    3255                 :        201 :   gimple_call_set_fndecl (stmt, fn);
    3256                 :        201 :   gimple_call_set_fntype (stmt, TREE_TYPE (fn));
    3257                 :        201 :   gimple_call_set_arg (stmt, 0, dest);
    3258                 :        201 :   gimple_call_set_arg (stmt, 1, fmt);
    3259                 :        399 :   for (unsigned i = 2; i < gimple_call_num_args (stmt) - 2; ++i)
    3260                 :        198 :     gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
    3261                 :        201 :   gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
    3262                 :        201 :   fold_stmt (gsi);
    3263                 :        201 :   return true;
    3264                 :            : }
    3265                 :            : 
    3266                 :            : /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
    3267                 :            :    ORIG may be null if this is a 2-argument call.  We don't attempt to
    3268                 :            :    simplify calls with more than 3 arguments.
    3269                 :            : 
    3270                 :            :    Return true if simplification was possible, otherwise false.  */
    3271                 :            : 
    3272                 :            : bool
    3273                 :       1565 : gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
    3274                 :            : {
    3275                 :       1565 :   gimple *stmt = gsi_stmt (*gsi);
    3276                 :       1565 :   tree dest = gimple_call_arg (stmt, 0);
    3277                 :       1565 :   tree fmt = gimple_call_arg (stmt, 1);
    3278                 :       1565 :   tree orig = NULL_TREE;
    3279                 :       1565 :   const char *fmt_str = NULL;
    3280                 :            : 
    3281                 :            :   /* Verify the required arguments in the original call.  We deal with two
    3282                 :            :      types of sprintf() calls: 'sprintf (str, fmt)' and
    3283                 :            :      'sprintf (dest, "%s", orig)'.  */
    3284                 :       1565 :   if (gimple_call_num_args (stmt) > 3)
    3285                 :            :     return false;
    3286                 :            : 
    3287                 :       1192 :   if (gimple_call_num_args (stmt) == 3)
    3288                 :       1095 :     orig = gimple_call_arg (stmt, 2);
    3289                 :            : 
    3290                 :            :   /* Check whether the format is a literal string constant.  */
    3291                 :       1192 :   fmt_str = c_getstr (fmt);
    3292                 :       1192 :   if (fmt_str == NULL)
    3293                 :            :     return false;
    3294                 :            : 
    3295                 :       1192 :   if (!init_target_chars ())
    3296                 :            :     return false;
    3297                 :            : 
    3298                 :            :   /* If the format doesn't contain % args or %%, use strcpy.  */
    3299                 :       1192 :   if (strchr (fmt_str, target_percent) == NULL)
    3300                 :            :     {
    3301                 :        218 :       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
    3302                 :            : 
    3303                 :        109 :       if (!fn)
    3304                 :            :         return false;
    3305                 :            : 
    3306                 :            :       /* Don't optimize sprintf (buf, "abc", ptr++).  */
    3307                 :        109 :       if (orig)
    3308                 :            :         return false;
    3309                 :            : 
    3310                 :            :       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
    3311                 :            :          'format' is known to contain no % formats.  */
    3312                 :         96 :       gimple_seq stmts = NULL;
    3313                 :         96 :       gimple *repl = gimple_build_call (fn, 2, dest, fmt);
    3314                 :            : 
    3315                 :            :       /* Propagate the NO_WARNING bit to avoid issuing the same
    3316                 :            :          warning more than once.  */
    3317                 :         96 :       if (gimple_no_warning_p (stmt))
    3318                 :          0 :         gimple_set_no_warning (repl, true);
    3319                 :            : 
    3320                 :         96 :       gimple_seq_add_stmt_without_update (&stmts, repl);
    3321                 :         96 :       if (tree lhs = gimple_call_lhs (stmt))
    3322                 :            :         {
    3323                 :          3 :           repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs),
    3324                 :          3 :                                                           strlen (fmt_str)));
    3325                 :          3 :           gimple_seq_add_stmt_without_update (&stmts, repl);
    3326                 :          3 :           gsi_replace_with_seq_vops (gsi, stmts);
    3327                 :            :           /* gsi now points at the assignment to the lhs, get a
    3328                 :            :              stmt iterator to the memcpy call.
    3329                 :            :              ???  We can't use gsi_for_stmt as that doesn't work when the
    3330                 :            :              CFG isn't built yet.  */
    3331                 :          3 :           gimple_stmt_iterator gsi2 = *gsi;
    3332                 :          3 :           gsi_prev (&gsi2);
    3333                 :          3 :           fold_stmt (&gsi2);
    3334                 :            :         }
    3335                 :            :       else
    3336                 :            :         {
    3337                 :         93 :           gsi_replace_with_seq_vops (gsi, stmts);
    3338                 :         93 :           fold_stmt (gsi);
    3339                 :            :         }
    3340                 :         96 :       return true;
    3341                 :            :     }
    3342                 :            : 
    3343                 :            :   /* If the format is "%s", use strcpy if the result isn't used.  */
    3344                 :       1083 :   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
    3345                 :            :     {
    3346                 :        137 :       tree fn;
    3347                 :        274 :       fn = builtin_decl_implicit (BUILT_IN_STRCPY);
    3348                 :            : 
    3349                 :        137 :       if (!fn)
    3350                 :            :         return false;
    3351                 :            : 
    3352                 :            :       /* Don't crash on sprintf (str1, "%s").  */
    3353                 :        137 :       if (!orig)
    3354                 :            :         return false;
    3355                 :            : 
    3356                 :        136 :       tree orig_len = NULL_TREE;
    3357                 :        136 :       if (gimple_call_lhs (stmt))
    3358                 :            :         {
    3359                 :         28 :           orig_len = get_maxval_strlen (orig, SRK_STRLEN);
    3360                 :         28 :           if (!orig_len)
    3361                 :            :             return false;
    3362                 :            :         }
    3363                 :            : 
    3364                 :            :       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
    3365                 :        111 :       gimple_seq stmts = NULL;
    3366                 :        111 :       gimple *repl = gimple_build_call (fn, 2, dest, orig);
    3367                 :            : 
    3368                 :            :       /* Propagate the NO_WARNING bit to avoid issuing the same
    3369                 :            :          warning more than once.  */
    3370                 :        111 :       if (gimple_no_warning_p (stmt))
    3371                 :          1 :         gimple_set_no_warning (repl, true);
    3372                 :            : 
    3373                 :        111 :       gimple_seq_add_stmt_without_update (&stmts, repl);
    3374                 :        111 :       if (tree lhs = gimple_call_lhs (stmt))
    3375                 :            :         {
    3376                 :          6 :           if (!useless_type_conversion_p (TREE_TYPE (lhs),
    3377                 :          3 :                                           TREE_TYPE (orig_len)))
    3378                 :          3 :             orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
    3379                 :          3 :           repl = gimple_build_assign (lhs, orig_len);
    3380                 :          3 :           gimple_seq_add_stmt_without_update (&stmts, repl);
    3381                 :          3 :           gsi_replace_with_seq_vops (gsi, stmts);
    3382                 :            :           /* gsi now points at the assignment to the lhs, get a
    3383                 :            :              stmt iterator to the memcpy call.
    3384                 :            :              ???  We can't use gsi_for_stmt as that doesn't work when the
    3385                 :            :              CFG isn't built yet.  */
    3386                 :          3 :           gimple_stmt_iterator gsi2 = *gsi;
    3387                 :          3 :           gsi_prev (&gsi2);
    3388                 :          3 :           fold_stmt (&gsi2);
    3389                 :            :         }
    3390                 :            :       else
    3391                 :            :         {
    3392                 :        108 :           gsi_replace_with_seq_vops (gsi, stmts);
    3393                 :        108 :           fold_stmt (gsi);
    3394                 :            :         }
    3395                 :        111 :       return true;
    3396                 :            :     }
    3397                 :            :   return false;
    3398                 :            : }
    3399                 :            : 
    3400                 :            : /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
    3401                 :            :    FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
    3402                 :            :    attempt to simplify calls with more than 4 arguments.
    3403                 :            : 
    3404                 :            :    Return true if simplification was possible, otherwise false.  */
    3405                 :            : 
    3406                 :            : bool
    3407                 :       1184 : gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
    3408                 :            : {
    3409                 :       1184 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3410                 :       1184 :   tree dest = gimple_call_arg (stmt, 0);
    3411                 :       1184 :   tree destsize = gimple_call_arg (stmt, 1);
    3412                 :       1184 :   tree fmt = gimple_call_arg (stmt, 2);
    3413                 :       1184 :   tree orig = NULL_TREE;
    3414                 :       1184 :   const char *fmt_str = NULL;
    3415                 :            : 
    3416                 :       1184 :   if (gimple_call_num_args (stmt) > 4)
    3417                 :            :     return false;
    3418                 :            : 
    3419                 :        680 :   if (gimple_call_num_args (stmt) == 4)
    3420                 :        556 :     orig = gimple_call_arg (stmt, 3);
    3421                 :            : 
    3422                 :        680 :   if (!tree_fits_uhwi_p (destsize))
    3423                 :            :     return false;
    3424                 :        651 :   unsigned HOST_WIDE_INT destlen = tree_to_uhwi (destsize);
    3425                 :            : 
    3426                 :            :   /* Check whether the format is a literal string constant.  */
    3427                 :        651 :   fmt_str = c_getstr (fmt);
    3428                 :        651 :   if (fmt_str == NULL)
    3429                 :            :     return false;
    3430                 :            : 
    3431                 :        651 :   if (!init_target_chars ())
    3432                 :            :     return false;
    3433                 :            : 
    3434                 :            :   /* If the format doesn't contain % args or %%, use strcpy.  */
    3435                 :        651 :   if (strchr (fmt_str, target_percent) == NULL)
    3436                 :            :     {
    3437                 :        242 :       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
    3438                 :        121 :       if (!fn)
    3439                 :            :         return false;
    3440                 :            : 
    3441                 :            :       /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
    3442                 :        121 :       if (orig)
    3443                 :            :         return false;
    3444                 :            : 
    3445                 :            :       /* We could expand this as
    3446                 :            :          memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
    3447                 :            :          or to
    3448                 :            :          memcpy (str, fmt_with_nul_at_cstm1, cst);
    3449                 :            :          but in the former case that might increase code size
    3450                 :            :          and in the latter case grow .rodata section too much.
    3451                 :            :          So punt for now.  */
    3452                 :        121 :       size_t len = strlen (fmt_str);
    3453                 :        121 :       if (len >= destlen)
    3454                 :            :         return false;
    3455                 :            : 
    3456                 :         91 :       gimple_seq stmts = NULL;
    3457                 :         91 :       gimple *repl = gimple_build_call (fn, 2, dest, fmt);
    3458                 :         91 :       gimple_seq_add_stmt_without_update (&stmts, repl);
    3459                 :         91 :       if (tree lhs = gimple_call_lhs (stmt))
    3460                 :            :         {
    3461                 :          6 :           repl = gimple_build_assign (lhs,
    3462                 :          3 :                                       build_int_cst (TREE_TYPE (lhs), len));
    3463                 :          3 :           gimple_seq_add_stmt_without_update (&stmts, repl);
    3464                 :          3 :           gsi_replace_with_seq_vops (gsi, stmts);
    3465                 :            :           /* gsi now points at the assignment to the lhs, get a
    3466                 :            :              stmt iterator to the memcpy call.
    3467                 :            :              ???  We can't use gsi_for_stmt as that doesn't work when the
    3468                 :            :              CFG isn't built yet.  */
    3469                 :          3 :           gimple_stmt_iterator gsi2 = *gsi;
    3470                 :          3 :           gsi_prev (&gsi2);
    3471                 :          3 :           fold_stmt (&gsi2);
    3472                 :            :         }
    3473                 :            :       else
    3474                 :            :         {
    3475                 :         88 :           gsi_replace_with_seq_vops (gsi, stmts);
    3476                 :         88 :           fold_stmt (gsi);
    3477                 :            :         }
    3478                 :         91 :       return true;
    3479                 :            :     }
    3480                 :            : 
    3481                 :            :   /* If the format is "%s", use strcpy if the result isn't used.  */
    3482                 :        530 :   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
    3483                 :            :     {
    3484                 :        330 :       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
    3485                 :        165 :       if (!fn)
    3486                 :            :         return false;
    3487                 :            : 
    3488                 :            :       /* Don't crash on snprintf (str1, cst, "%s").  */
    3489                 :        165 :       if (!orig)
    3490                 :            :         return false;
    3491                 :            : 
    3492                 :        165 :       tree orig_len = get_maxval_strlen (orig, SRK_STRLEN);
    3493                 :        165 :       if (!orig_len || TREE_CODE (orig_len) != INTEGER_CST)
    3494                 :            :         return false;
    3495                 :            : 
    3496                 :            :       /* We could expand this as
    3497                 :            :          memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
    3498                 :            :          or to
    3499                 :            :          memcpy (str1, str2_with_nul_at_cstm1, cst);
    3500                 :            :          but in the former case that might increase code size
    3501                 :            :          and in the latter case grow .rodata section too much.
    3502                 :            :          So punt for now.  */
    3503                 :         73 :       if (compare_tree_int (orig_len, destlen) >= 0)
    3504                 :            :         return false;
    3505                 :            : 
    3506                 :            :       /* Convert snprintf (str1, cst, "%s", str2) into
    3507                 :            :          strcpy (str1, str2) if strlen (str2) < cst.  */
    3508                 :         57 :       gimple_seq stmts = NULL;
    3509                 :         57 :       gimple *repl = gimple_build_call (fn, 2, dest, orig);
    3510                 :         57 :       gimple_seq_add_stmt_without_update (&stmts, repl);
    3511                 :         57 :       if (tree lhs = gimple_call_lhs (stmt))
    3512                 :            :         {
    3513                 :          6 :           if (!useless_type_conversion_p (TREE_TYPE (lhs),
    3514                 :          3 :                                           TREE_TYPE (orig_len)))
    3515                 :          3 :             orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
    3516                 :          3 :           repl = gimple_build_assign (lhs, orig_len);
    3517                 :          3 :           gimple_seq_add_stmt_without_update (&stmts, repl);
    3518                 :          3 :           gsi_replace_with_seq_vops (gsi, stmts);
    3519                 :            :           /* gsi now points at the assignment to the lhs, get a
    3520                 :            :              stmt iterator to the memcpy call.
    3521                 :            :              ???  We can't use gsi_for_stmt as that doesn't work when the
    3522                 :            :              CFG isn't built yet.  */
    3523                 :          3 :           gimple_stmt_iterator gsi2 = *gsi;
    3524                 :          3 :           gsi_prev (&gsi2);
    3525                 :          3 :           fold_stmt (&gsi2);
    3526                 :            :         }
    3527                 :            :       else
    3528                 :            :         {
    3529                 :         54 :           gsi_replace_with_seq_vops (gsi, stmts);
    3530                 :         54 :           fold_stmt (gsi);
    3531                 :            :         }
    3532                 :         57 :       return true;
    3533                 :            :     }
    3534                 :            :   return false;
    3535                 :            : }
    3536                 :            : 
    3537                 :            : /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
    3538                 :            :    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
    3539                 :            :    more than 3 arguments, and ARG may be null in the 2-argument case.
    3540                 :            : 
    3541                 :            :    Return NULL_TREE if no simplification was possible, otherwise return the
    3542                 :            :    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
    3543                 :            :    code of the function to be simplified.  */
    3544                 :            : 
    3545                 :            : static bool 
    3546                 :      16396 : gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
    3547                 :            :                              tree fp, tree fmt, tree arg,
    3548                 :            :                              enum built_in_function fcode)
    3549                 :            : {
    3550                 :      16396 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3551                 :      16396 :   tree fn_fputc, fn_fputs;
    3552                 :      16396 :   const char *fmt_str = NULL;
    3553                 :            : 
    3554                 :            :   /* If the return value is used, don't do the transformation.  */
    3555                 :      16396 :   if (gimple_call_lhs (stmt) != NULL_TREE)
    3556                 :            :     return false;
    3557                 :            : 
    3558                 :            :   /* Check whether the format is a literal string constant.  */
    3559                 :      11686 :   fmt_str = c_getstr (fmt);
    3560                 :      11686 :   if (fmt_str == NULL)
    3561                 :            :     return false;
    3562                 :            : 
    3563                 :      11367 :   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
    3564                 :            :     {
    3565                 :            :       /* If we're using an unlocked function, assume the other
    3566                 :            :          unlocked functions exist explicitly.  */
    3567                 :         86 :       fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
    3568                 :         86 :       fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
    3569                 :            :     }
    3570                 :            :   else
    3571                 :            :     {
    3572                 :      11281 :       fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
    3573                 :      11281 :       fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
    3574                 :            :     }
    3575                 :            : 
    3576                 :      11367 :   if (!init_target_chars ())
    3577                 :            :     return false;
    3578                 :            : 
    3579                 :            :   /* If the format doesn't contain % args or %%, use strcpy.  */
    3580                 :      11367 :   if (strchr (fmt_str, target_percent) == NULL)
    3581                 :            :     {
    3582                 :       2699 :       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
    3583                 :       2629 :           && arg)
    3584                 :            :         return false;
    3585                 :            : 
    3586                 :            :       /* If the format specifier was "", fprintf does nothing.  */
    3587                 :       2699 :       if (fmt_str[0] == '\0')
    3588                 :            :         {
    3589                 :         58 :           replace_call_with_value (gsi, NULL_TREE);
    3590                 :         58 :           return true;
    3591                 :            :         }
    3592                 :            : 
    3593                 :            :       /* When "string" doesn't contain %, replace all cases of
    3594                 :            :          fprintf (fp, string) with fputs (string, fp).  The fputs
    3595                 :            :          builtin will take care of special cases like length == 1.  */
    3596                 :       2641 :       if (fn_fputs)
    3597                 :            :         {
    3598                 :       2641 :           gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
    3599                 :       2641 :           replace_call_with_call_and_fold (gsi, repl);
    3600                 :       2641 :           return true;
    3601                 :            :         }
    3602                 :            :     }
    3603                 :            : 
    3604                 :            :   /* The other optimizations can be done only on the non-va_list variants.  */
    3605                 :       8668 :   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
    3606                 :            :     return false;
    3607                 :            : 
    3608                 :            :   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
    3609                 :       7466 :   else if (strcmp (fmt_str, target_percent_s) == 0)
    3610                 :            :     {
    3611                 :        498 :       if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
    3612                 :            :         return false;
    3613                 :        249 :       if (fn_fputs)
    3614                 :            :         {
    3615                 :        249 :           gcall *repl = gimple_build_call (fn_fputs, 2, arg, fp);
    3616                 :        249 :           replace_call_with_call_and_fold (gsi, repl);
    3617                 :        249 :           return true;
    3618                 :            :         }
    3619                 :            :     }
    3620                 :            : 
    3621                 :            :   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
    3622                 :       7217 :   else if (strcmp (fmt_str, target_percent_c) == 0)
    3623                 :            :     {
    3624                 :         56 :       if (!arg
    3625                 :        112 :           || ! useless_type_conversion_p (integer_type_node, TREE_TYPE (arg)))
    3626                 :          0 :         return false;
    3627                 :         56 :       if (fn_fputc)
    3628                 :            :         {
    3629                 :         56 :           gcall *repl = gimple_build_call (fn_fputc, 2, arg, fp);
    3630                 :         56 :           replace_call_with_call_and_fold (gsi, repl);
    3631                 :         56 :           return true;
    3632                 :            :         }
    3633                 :            :     }
    3634                 :            : 
    3635                 :            :   return false;
    3636                 :            : }
    3637                 :            : 
    3638                 :            : /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
    3639                 :            :    FMT and ARG are the arguments to the call; we don't fold cases with
    3640                 :            :    more than 2 arguments, and ARG may be null if this is a 1-argument case.
    3641                 :            : 
    3642                 :            :    Return NULL_TREE if no simplification was possible, otherwise return the
    3643                 :            :    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
    3644                 :            :    code of the function to be simplified.  */
    3645                 :            : 
    3646                 :            : static bool
    3647                 :      60049 : gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
    3648                 :            :                             tree arg, enum built_in_function fcode)
    3649                 :            : {
    3650                 :      60049 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    3651                 :      60049 :   tree fn_putchar, fn_puts, newarg;
    3652                 :      60049 :   const char *fmt_str = NULL;
    3653                 :            : 
    3654                 :            :   /* If the return value is used, don't do the transformation.  */
    3655                 :      60049 :   if (gimple_call_lhs (stmt) != NULL_TREE)
    3656                 :            :     return false;
    3657                 :            : 
    3658                 :            :   /* Check whether the format is a literal string constant.  */
    3659                 :      56617 :   fmt_str = c_getstr (fmt);
    3660                 :      56617 :   if (fmt_str == NULL)
    3661                 :            :     return false;
    3662                 :            : 
    3663                 :      53490 :   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
    3664                 :            :     {
    3665                 :            :       /* If we're using an unlocked function, assume the other
    3666                 :            :          unlocked functions exist explicitly.  */
    3667                 :         86 :       fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
    3668                 :         86 :       fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
    3669                 :            :     }
    3670                 :            :   else
    3671                 :            :     {
    3672                 :      53404 :       fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
    3673                 :      53404 :       fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
    3674                 :            :     }
    3675                 :            : 
    3676                 :      53490 :   if (!init_target_chars ())
    3677                 :            :     return false;
    3678                 :            : 
    3679                 :      53490 :   if (strcmp (fmt_str, target_percent_s) == 0
    3680                 :      52868 :       || strchr (fmt_str, target_percent) == NULL)
    3681                 :            :     {
    3682                 :       7999 :       const char *str;
    3683                 :            : 
    3684                 :       7999 :       if (strcmp (fmt_str, target_percent_s) == 0)
    3685                 :            :         {
    3686                 :        622 :           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
    3687                 :            :             return false;
    3688                 :            : 
    3689                 :        596 :           if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
    3690                 :            :             return false;
    3691                 :            : 
    3692                 :        293 :           str = c_getstr (arg);
    3693                 :        293 :           if (str == NULL)
    3694                 :            :             return false;
    3695                 :            :         }
    3696                 :            :       else
    3697                 :            :         {
    3698                 :            :           /* The format specifier doesn't contain any '%' characters.  */
    3699                 :       7377 :           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
    3700                 :       7234 :               && arg)
    3701                 :            :             return false;
    3702                 :            :           str = fmt_str;
    3703                 :            :         }
    3704                 :            : 
    3705                 :            :       /* If the string was "", printf does nothing.  */
    3706                 :       5572 :       if (str[0] == '\0')
    3707                 :            :         {
    3708                 :        110 :           replace_call_with_value (gsi, NULL_TREE);
    3709                 :        110 :           return true;
    3710                 :            :         }
    3711                 :            : 
    3712                 :            :       /* If the string has length of 1, call putchar.  */
    3713                 :       5462 :       if (str[1] == '\0')
    3714                 :            :         {
    3715                 :            :           /* Given printf("c"), (where c is any one character,)
    3716                 :            :              convert "c"[0] to an int and pass that to the replacement
    3717                 :            :              function.  */
    3718                 :        498 :           newarg = build_int_cst (integer_type_node, str[0]);
    3719                 :        498 :           if (fn_putchar)
    3720                 :            :             {
    3721                 :        498 :               gcall *repl = gimple_build_call (fn_putchar, 1, newarg);
    3722                 :        498 :               replace_call_with_call_and_fold (gsi, repl);
    3723                 :        498 :               return true;
    3724                 :            :             }
    3725                 :            :         }
    3726                 :            :       else
    3727                 :            :         {
    3728                 :            :           /* If the string was "string\n", call puts("string").  */
    3729                 :       4964 :           size_t len = strlen (str);
    3730                 :       4964 :           if ((unsigned char)str[len - 1] == target_newline
    3731                 :       3808 :               && (size_t) (int) len == len
    3732                 :       3808 :               && (int) len > 0)
    3733                 :            :             {
    3734                 :       3808 :               char *newstr;
    3735                 :            : 
    3736                 :            :               /* Create a NUL-terminated string that's one char shorter
    3737                 :            :                  than the original, stripping off the trailing '\n'.  */
    3738                 :       3808 :               newstr = xstrdup (str);
    3739                 :       3808 :               newstr[len - 1] = '\0';
    3740                 :       3808 :               newarg = build_string_literal (len, newstr);
    3741                 :       3808 :               free (newstr);
    3742                 :       3808 :               if (fn_puts)
    3743                 :            :                 {
    3744                 :       3808 :                   gcall *repl = gimple_build_call (fn_puts, 1, newarg);
    3745                 :       3808 :                   replace_call_with_call_and_fold (gsi, repl);
    3746                 :       3808 :                   return true;
    3747                 :            :                 }
    3748                 :            :             }
    3749                 :            :           else
    3750                 :            :             /* We'd like to arrange to call fputs(string,stdout) here,
    3751                 :            :                but we need stdout and don't have a way to get it yet.  */
    3752                 :            :             return false;
    3753                 :            :         }
    3754                 :            :     }
    3755                 :            : 
    3756                 :            :   /* The other optimizations can be done only on the non-va_list variants.  */
    3757                 :      45491 :   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
    3758                 :            :     return false;
    3759                 :            : 
    3760                 :            :   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
    3761                 :      45212 :   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
    3762                 :            :     {
    3763                 :        322 :       if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
    3764                 :            :         return false;
    3765                 :        161 :       if (fn_puts)
    3766                 :            :         {
    3767                 :        161 :           gcall *repl = gimple_build_call (fn_puts, 1, arg);
    3768                 :        161 :           replace_call_with_call_and_fold (gsi, repl);
    3769                 :        161 :           return true;
    3770                 :            :         }
    3771                 :            :     }
    3772                 :            : 
    3773                 :            :   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
    3774                 :      45051 :   else if (strcmp (fmt_str, target_percent_c) == 0)
    3775                 :            :     {
    3776                 :        104 :       if (!arg || ! useless_type_conversion_p (integer_type_node,
    3777                 :         52 :                                                TREE_TYPE (arg)))
    3778                 :          0 :         return false;
    3779                 :         52 :       if (fn_putchar)
    3780                 :            :         {
    3781                 :         52 :           gcall *repl = gimple_build_call (fn_putchar, 1, arg);
    3782                 :         52 :           replace_call_with_call_and_fold (gsi, repl);
    3783                 :         52 :           return true;
    3784                 :            :         }
    3785                 :            :     }
    3786                 :            : 
    3787                 :            :   return false;
    3788                 :            : }
    3789                 :            : 
    3790                 :            : 
    3791                 :            : 
    3792                 :            : /* Fold a call to __builtin_strlen with known length LEN.  */
    3793                 :            : 
    3794                 :            : static bool
    3795                 :     103723 : gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
    3796                 :            : {
    3797                 :     103723 :   gimple *stmt = gsi_stmt (*gsi);
    3798                 :     103723 :   tree arg = gimple_call_arg (stmt, 0);
    3799                 :            : 
    3800                 :     103723 :   wide_int minlen;
    3801                 :     103723 :   wide_int maxlen;
    3802                 :            : 
    3803                 :     103723 :   c_strlen_data lendata = { };
    3804                 :     103723 :   if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
    3805                 :      28420 :       && !lendata.decl
    3806                 :      25198 :       && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
    3807                 :     128816 :       && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
    3808                 :            :     {
    3809                 :            :       /* The range of lengths refers to either a single constant
    3810                 :            :          string or to the longest and shortest constant string
    3811                 :            :          referenced by the argument of the strlen() call, or to
    3812                 :            :          the strings that can possibly be stored in the arrays
    3813                 :            :          the argument refers to.  */
    3814                 :      25093 :       minlen = wi::to_wide (lendata.minlen);
    3815                 :      25093 :       maxlen = wi::to_wide (lendata.maxlen);
    3816                 :            :     }
    3817                 :            :   else
    3818                 :            :     {
    3819                 :      78630 :       unsigned prec = TYPE_PRECISION (sizetype);
    3820                 :            : 
    3821                 :      78630 :       minlen = wi::shwi (0, prec);
    3822                 :      78630 :       maxlen = wi::to_wide (max_object_size (), prec) - 2;
    3823                 :            :     }
    3824                 :            : 
    3825                 :     103723 :   if (minlen == maxlen)
    3826                 :            :     {
    3827                 :            :       /* Fold the strlen call to a constant.  */
    3828                 :        276 :       tree type = TREE_TYPE (lendata.minlen);
    3829                 :        276 :       tree len = force_gimple_operand_gsi (gsi,
    3830                 :            :                                            wide_int_to_tree (type, minlen),
    3831                 :            :                                            true, NULL, true, GSI_SAME_STMT);
    3832                 :        276 :       replace_call_with_value (gsi, len);
    3833                 :        276 :       return true;
    3834                 :            :     }
    3835                 :            : 
    3836                 :            :   /* Set the strlen() range to [0, MAXLEN].  */
    3837                 :     103447 :   if (tree lhs = gimple_call_lhs (stmt))
    3838                 :     103445 :     set_strlen_range (lhs, minlen, maxlen);
    3839                 :            : 
    3840                 :            :   return false;
    3841                 :            : }
    3842                 :            : 
    3843                 :            : /* Fold a call to __builtin_acc_on_device.  */
    3844                 :            : 
    3845                 :            : static bool
    3846                 :       1714 : gimple_fold_builtin_acc_on_device (gimple_stmt_iterator *gsi, tree arg0)
    3847                 :            : {
    3848                 :            :   /* Defer folding until we know which compiler we're in.  */
    3849                 :       1714 :   if (symtab->state != EXPANSION)
    3850                 :            :     return false;
    3851                 :            : 
    3852                 :        420 :   unsigned val_host = GOMP_DEVICE_HOST;
    3853                 :        420 :   unsigned val_dev = GOMP_DEVICE_NONE;
    3854                 :            : 
    3855                 :            : #ifdef ACCEL_COMPILER
    3856                 :            :   val_host = GOMP_DEVICE_NOT_HOST;
    3857                 :            :   val_dev = ACCEL_COMPILER_acc_device;
    3858                 :            : #endif
    3859                 :            : 
    3860                 :        420 :   location_t loc = gimple_location (gsi_stmt (*gsi));
    3861                 :            :   
    3862                 :        420 :   tree host_eq = make_ssa_name (boolean_type_node);
    3863                 :        420 :   gimple *host_ass = gimple_build_assign
    3864                 :        420 :     (host_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_host));
    3865                 :        420 :   gimple_set_location (host_ass, loc);
    3866                 :        420 :   gsi_insert_before (gsi, host_ass, GSI_SAME_STMT);
    3867                 :            : 
    3868                 :        420 :   tree dev_eq = make_ssa_name (boolean_type_node);
    3869                 :        420 :   gimple *dev_ass = gimple_build_assign
    3870                 :        420 :     (dev_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_dev));
    3871                 :        420 :   gimple_set_location (dev_ass, loc);
    3872                 :        420 :   gsi_insert_before (gsi, dev_ass, GSI_SAME_STMT);
    3873                 :            : 
    3874                 :        420 :   tree result = make_ssa_name (boolean_type_node);
    3875                 :        420 :   gimple *result_ass = gimple_build_assign
    3876                 :        420 :     (result, BIT_IOR_EXPR, host_eq, dev_eq);
    3877                 :        420 :   gimple_set_location (result_ass, loc);
    3878                 :        420 :   gsi_insert_before (gsi, result_ass, GSI_SAME_STMT);
    3879                 :            : 
    3880                 :        420 :   replace_call_with_value (gsi, result);
    3881                 :            : 
    3882                 :        420 :   return true;
    3883                 :            : }
    3884                 :            : 
    3885                 :            : /* Fold realloc (0, n) -> malloc (n).  */
    3886                 :            : 
    3887                 :            : static bool
    3888                 :       1032 : gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
    3889                 :            : {
    3890                 :       1032 :   gimple *stmt = gsi_stmt (*gsi);
    3891                 :       1032 :   tree arg = gimple_call_arg (stmt, 0);
    3892                 :       1032 :   tree size = gimple_call_arg (stmt, 1);
    3893                 :            : 
    3894                 :       1032 :   if (operand_equal_p (arg, null_pointer_node, 0))
    3895                 :            :     {
    3896                 :          5 :       tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
    3897                 :          5 :       if (fn_malloc)
    3898                 :            :         {
    3899                 :          5 :           gcall *repl = gimple_build_call (fn_malloc, 1, size);
    3900                 :          5 :           replace_call_with_call_and_fold (gsi, repl);
    3901                 :          5 :           return true;
    3902                 :            :         }
    3903                 :            :     }
    3904                 :            :   return false;
    3905                 :            : }
    3906                 :            : 
    3907                 :            : /* Fold the non-target builtin at *GSI and return whether any simplification
    3908                 :            :    was made.  */
    3909                 :            : 
    3910                 :            : static bool
    3911                 :    7200390 : gimple_fold_builtin (gimple_stmt_iterator *gsi)
    3912                 :            : {
    3913                 :    7200390 :   gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
    3914                 :    7200390 :   tree callee = gimple_call_fndecl (stmt);
    3915                 :            : 
    3916                 :            :   /* Give up for always_inline inline builtins until they are
    3917                 :            :      inlined.  */
    3918                 :    7200390 :   if (avoid_folding_inline_builtin (callee))
    3919                 :            :     return false;
    3920                 :            : 
    3921                 :    7199220 :   unsigned n = gimple_call_num_args (stmt);
    3922                 :    7199220 :   enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
    3923                 :    7199220 :   switch (fcode)
    3924                 :            :     {
    3925                 :        135 :     case BUILT_IN_BCMP:
    3926                 :        135 :       return gimple_fold_builtin_bcmp (gsi);
    3927                 :        331 :     case BUILT_IN_BCOPY:
    3928                 :        331 :       return gimple_fold_builtin_bcopy (gsi);
    3929                 :        277 :     case BUILT_IN_BZERO:
    3930                 :        277 :       return gimple_fold_builtin_bzero (gsi);
    3931                 :            : 
    3932                 :     216912 :     case BUILT_IN_MEMSET:
    3933                 :     216912 :       return gimple_fold_builtin_memset (gsi,
    3934                 :            :                                          gimple_call_arg (stmt, 1),
    3935                 :     216912 :                                          gimple_call_arg (stmt, 2));
    3936                 :     550278 :     case BUILT_IN_MEMCPY:
    3937                 :     550278 :     case BUILT_IN_MEMPCPY:
    3938                 :     550278 :     case BUILT_IN_MEMMOVE:
    3939                 :     550278 :       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
    3940                 :     550278 :                                             gimple_call_arg (stmt, 1), fcode);
    3941                 :       5162 :     case BUILT_IN_SPRINTF_CHK:
    3942                 :       5162 :     case BUILT_IN_VSPRINTF_CHK:
    3943                 :       5162 :       return gimple_fold_builtin_sprintf_chk (gsi, fcode);
    3944                 :       1790 :     case BUILT_IN_STRCAT_CHK:
    3945                 :       1790 :       return gimple_fold_builtin_strcat_chk (gsi);
    3946                 :       1379 :     case BUILT_IN_STRNCAT_CHK:
    3947                 :       1379 :       return gimple_fold_builtin_strncat_chk (gsi);
    3948                 :     103723 :     case BUILT_IN_STRLEN:
    3949                 :     103723 :       return gimple_fold_builtin_strlen (gsi);
    3950                 :      23269 :     case BUILT_IN_STRCPY:
    3951                 :      23269 :       return gimple_fold_builtin_strcpy (gsi,
    3952                 :            :                                          gimple_call_arg (stmt, 0),
    3953                 :      23269 :                                          gimple_call_arg (stmt, 1));
    3954                 :      18381 :     case BUILT_IN_STRNCPY:
    3955                 :      18381 :       return gimple_fold_builtin_strncpy (gsi,
    3956                 :            :                                           gimple_call_arg (stmt, 0),
    3957                 :            :                                           gimple_call_arg (stmt, 1),
    3958                 :      18381 :                                           gimple_call_arg (stmt, 2));
    3959                 :       7236 :     case BUILT_IN_STRCAT:
    3960                 :       7236 :       return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
    3961                 :       7236 :                                          gimple_call_arg (stmt, 1));
    3962                 :       6607 :     case BUILT_IN_STRNCAT:
    3963                 :       6607 :       return gimple_fold_builtin_strncat (gsi);
    3964                 :       4613 :     case BUILT_IN_INDEX:
    3965                 :       4613 :     case BUILT_IN_STRCHR:
    3966                 :       4613 :       return gimple_fold_builtin_strchr (gsi, false);
    3967                 :        712 :     case BUILT_IN_RINDEX:
    3968                 :        712 :     case BUILT_IN_STRRCHR:
    3969                 :        712 :       return gimple_fold_builtin_strchr (gsi, true);
    3970                 :       3000 :     case BUILT_IN_STRSTR:
    3971                 :       3000 :       return gimple_fold_builtin_strstr (gsi);
    3972                 :      41538 :     case BUILT_IN_STRCMP:
    3973                 :      41538 :     case BUILT_IN_STRCMP_EQ:
    3974                 :      41538 :     case BUILT_IN_STRCASECMP:
    3975                 :      41538 :     case BUILT_IN_STRNCMP:
    3976                 :      41538 :     case BUILT_IN_STRNCMP_EQ:
    3977                 :      41538 :     case BUILT_IN_STRNCASECMP:
    3978                 :      41538 :       return gimple_fold_builtin_string_compare (gsi);
    3979                 :       6228 :     case BUILT_IN_MEMCHR:
    3980                 :       6228 :       return gimple_fold_builtin_memchr (gsi);
    3981                 :       5009 :     case BUILT_IN_FPUTS:
    3982                 :       5009 :       return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
    3983                 :       5009 :                                         gimple_call_arg (stmt, 1), false);
    3984                 :         43 :     case BUILT_IN_FPUTS_UNLOCKED:
    3985                 :         43 :       return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
    3986                 :         43 :                                         gimple_call_arg (stmt, 1), true);
    3987                 :      29539 :     case BUILT_IN_MEMCPY_CHK:
    3988                 :      29539 :     case BUILT_IN_MEMPCPY_CHK:
    3989                 :      29539 :     case BUILT_IN_MEMMOVE_CHK:
    3990                 :      29539 :     case BUILT_IN_MEMSET_CHK:
    3991                 :      29539 :       return gimple_fold_builtin_memory_chk (gsi,
    3992                 :            :                                              gimple_call_arg (stmt, 0),
    3993                 :            :                                              gimple_call_arg (stmt, 1),
    3994                 :            :                                              gimple_call_arg (stmt, 2),
    3995                 :            :                                              gimple_call_arg (stmt, 3),
    3996                 :      29539 :                                              fcode);
    3997                 :       4063 :     case BUILT_IN_STPCPY:
    3998                 :       4063 :       return gimple_fold_builtin_stpcpy (gsi);
    3999                 :       3119 :     case BUILT_IN_STRCPY_CHK:
    4000                 :       3119 :     case BUILT_IN_STPCPY_CHK:
    4001                 :       3119 :       return gimple_fold_builtin_stxcpy_chk (gsi,
    4002                 :            :                                              gimple_call_arg (stmt, 0),
    4003                 :            :                                              gimple_call_arg (stmt, 1),
    4004                 :            :                                              gimple_call_arg (stmt, 2),
    4005                 :       3119 :                                              fcode);
    4006                 :       3280 :     case BUILT_IN_STRNCPY_CHK:
    4007                 :       3280 :     case BUILT_IN_STPNCPY_CHK:
    4008                 :       3280 :       return gimple_fold_builtin_stxncpy_chk (gsi,
    4009                 :            :                                               gimple_call_arg (stmt, 0),
    4010                 :            :                                               gimple_call_arg (stmt, 1),
    4011                 :            :                                               gimple_call_arg (stmt, 2),
    4012                 :            :                                               gimple_call_arg (stmt, 3),
    4013                 :       3280 :                                               fcode);
    4014                 :       3008 :     case BUILT_IN_SNPRINTF_CHK:
    4015                 :       3008 :     case BUILT_IN_VSNPRINTF_CHK:
    4016                 :       3008 :       return gimple_fold_builtin_snprintf_chk (gsi, fcode);
    4017                 :            : 
    4018                 :     424525 :     case BUILT_IN_FPRINTF:
    4019                 :     424525 :     case BUILT_IN_FPRINTF_UNLOCKED:
    4020                 :     424525 :     case BUILT_IN_VFPRINTF:
    4021                 :     424525 :       if (n == 2 || n == 3)
    4022                 :      25064 :         return gimple_fold_builtin_fprintf (gsi,
    4023                 :            :                                             gimple_call_arg (stmt, 0),
    4024                 :            :                                             gimple_call_arg (stmt, 1),
    4025                 :            :                                             n == 3
    4026                 :      11035 :                                             ? gimple_call_arg (stmt, 2)
    4027                 :            :                                             : NULL_TREE,
    4028                 :      14029 :                                             fcode);
    4029                 :            :       break;
    4030                 :       2549 :     case BUILT_IN_FPRINTF_CHK:
    4031                 :       2549 :     case BUILT_IN_VFPRINTF_CHK:
    4032                 :       2549 :       if (n == 3 || n == 4)
    4033                 :       4360 :         return gimple_fold_builtin_fprintf (gsi,
    4034                 :            :                                             gimple_call_arg (stmt, 0),
    4035                 :            :                                             gimple_call_arg (stmt, 2),
    4036                 :            :                                             n == 4
    4037                 :       1993 :                                             ? gimple_call_arg (stmt, 3)
    4038                 :            :                                             : NULL_TREE,
    4039                 :       2367 :                                             fcode);
    4040                 :            :       break;
    4041                 :     140942 :     case BUILT_IN_PRINTF:
    4042                 :     140942 :     case BUILT_IN_PRINTF_UNLOCKED:
    4043                 :     140942 :     case BUILT_IN_VPRINTF:
    4044                 :     140942 :       if (n == 1 || n == 2)
    4045                 :     106384 :         return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
    4046                 :            :                                            n == 2
    4047                 :      48733 :                                            ? gimple_call_arg (stmt, 1)
    4048                 :      57651 :                                            : NULL_TREE, fcode);
    4049                 :            :       break;
    4050                 :       2571 :     case BUILT_IN_PRINTF_CHK:
    4051                 :       2571 :     case BUILT_IN_VPRINTF_CHK:
    4052                 :       2571 :       if (n == 2 || n == 3)
    4053                 :       4401 :         return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 1),
    4054                 :            :                                            n == 3
    4055                 :       2003 :                                            ? gimple_call_arg (stmt, 2)
    4056                 :       2398 :                                            : NULL_TREE, fcode);
    4057                 :            :       break;
    4058                 :       1714 :     case BUILT_IN_ACC_ON_DEVICE:
    4059                 :       1714 :       return gimple_fold_builtin_acc_on_device (gsi,
    4060                 :       1714 :                                                 gimple_call_arg (stmt, 0));
    4061                 :       1032 :     case BUILT_IN_REALLOC:
    4062                 :       1032 :       return gimple_fold_builtin_realloc (gsi);
    4063                 :            : 
    4064                 :    6080390 :     default:;
    4065                 :            :     }
    4066                 :            : 
    4067                 :            :   /* Try the generic builtin folder.  */
    4068                 :    6080390 :   bool ignore = (gimple_call_lhs (stmt) == NULL);
    4069                 :    6080390 :   tree result = fold_call_stmt (stmt, ignore);
    4070                 :    6080390 :   if (result)
    4071                 :            :     {
    4072                 :       3029 :       if (ignore)
    4073                 :        495 :         STRIP_NOPS (result);
    4074                 :            :       else
    4075                 :       2534 :         result = fold_convert (gimple_call_return_type (stmt), result);
    4076                 :       3029 :       if (!update_call_from_tree (gsi, result))
    4077                 :       1207 :         gimplify_and_update_call_from_tree (gsi, result);
    4078                 :       3029 :       return true;
    4079                 :            :     }
    4080                 :            : 
    4081                 :            :   return false;
    4082                 :            : }
    4083                 :            : 
    4084                 :            : /* Transform IFN_GOACC_DIM_SIZE and IFN_GOACC_DIM_POS internal
    4085                 :            :    function calls to constants, where possible.  */
    4086                 :            : 
    4087                 :            : static tree
    4088                 :      16610 : fold_internal_goacc_dim (const gimple *call)
    4089                 :            : {
    4090                 :      16610 :   int axis = oacc_get_ifn_dim_arg (call);
    4091                 :      16610 :   int size = oacc_get_fn_dim_size (current_function_decl, axis);
    4092                 :      16610 :   tree result = NULL_TREE;
    4093                 :      16610 :   tree type = TREE_TYPE (gimple_call_lhs (call));
    4094                 :            : 
    4095                 :      16610 :   switch (gimple_call_internal_fn (call))
    4096                 :            :     {
    4097                 :       7223 :     case IFN_GOACC_DIM_POS:
    4098                 :            :       /* If the size is 1, we know the answer.  */
    4099                 :       7223 :       if (size == 1)
    4100                 :       7223 :         result = build_int_cst (type, 0);
    4101                 :            :       break;
    4102                 :       9387 :     case IFN_GOACC_DIM_SIZE:
    4103                 :            :       /* If the size is not dynamic, we know the answer.  */
    4104                 :       9387 :       if (size)
    4105                 :       9387 :         result = build_int_cst (type, size);
    4106                 :            :       break;
    4107                 :            :     default:
    4108                 :            :       break;
    4109                 :            :     }
    4110                 :            : 
    4111                 :      16610 :   return result;
    4112                 :            : }
    4113                 :            : 
    4114                 :            : /* Return true if stmt is __atomic_compare_exchange_N call which is suitable
    4115                 :            :    for conversion into ATOMIC_COMPARE_EXCHANGE if the second argument is
    4116                 :            :    &var where var is only addressable because of such calls.  */
    4117                 :            : 
    4118                 :            : bool
    4119                 :   30399300 : optimize_atomic_compare_exchange_p (gimple *stmt)
    4120                 :            : {
    4121                 :   30399300 :   if (gimple_call_num_args (stmt) != 6
    4122                 :     722722 :       || !flag_inline_atomics
    4123                 :     722722 :       || !optimize
    4124                 :     722722 :       || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
    4125                 :     722716 :       || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
    4126                 :     455378 :       || !gimple_vdef (stmt)
    4127                 :   30793300 :       || !gimple_vuse (stmt))
    4128                 :   30005400 :     return false;
    4129                 :            : 
    4130                 :     393977 :   tree fndecl = gimple_call_fndecl (stmt);
    4131                 :     393977 :   switch (DECL_FUNCTION_CODE (fndecl))
    4132                 :            :     {
    4133                 :      39827 :     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
    4134                 :      39827 :     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
    4135                 :      39827 :     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
    4136                 :      39827 :     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
    4137                 :      39827 :     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
    4138                 :      39827 :       break;
    4139                 :            :     default:
    4140                 :            :       return false;
    4141                 :            :     }
    4142                 :            : 
    4143                 :      39827 :   tree expected = gimple_call_arg (stmt, 1);
    4144                 :      39827 :   if (TREE_CODE (expected) != ADDR_EXPR
    4145                 :      39827 :       || !SSA_VAR_P (TREE_OPERAND (expected, 0)))
    4146                 :            :     return false;
    4147                 :            : 
    4148                 :      38817 :   tree etype = TREE_TYPE (TREE_OPERAND (expected, 0));
    4149                 :      38817 :   if (!is_gimple_reg_type (etype)
    4150                 :      38685 :       || !auto_var_in_fn_p (TREE_OPERAND (expected, 0), current_function_decl)
    4151                 :      37360 :       || TREE_THIS_VOLATILE (etype)
    4152                 :      37360 :       || VECTOR_TYPE_P (etype)
    4153                 :      37360 :       || TREE_CODE (etype) == COMPLEX_TYPE
    4154                 :            :       /* Don't optimize floating point expected vars, VIEW_CONVERT_EXPRs
    4155                 :            :          might not preserve all the bits.  See PR71716.  */
    4156                 :      31944 :       || SCALAR_FLOAT_TYPE_P (etype)
    4157                 :      53919 :       || maybe_ne (TYPE_PRECISION (etype),
    4158                 :      30204 :                    GET_MODE_BITSIZE (TYPE_MODE (etype))))
    4159                 :      28599 :     return false;
    4160                 :            : 
    4161                 :      10218 :   tree weak = gimple_call_arg (stmt, 3);
    4162                 :      10218 :   if (!integer_zerop (weak) && !integer_onep (weak))
    4163                 :            :     return false;
    4164                 :            : 
    4165                 :      10218 :   tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    4166                 :      10218 :   tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
    4167                 :      10218 :   machine_mode mode = TYPE_MODE (itype);
    4168                 :            : 
    4169                 :      10218 :   if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
    4170                 :            :       == CODE_FOR_nothing
    4171                 :      10218 :       && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
    4172                 :            :     return false;
    4173                 :            : 
    4174                 :      20436 :   if (maybe_ne (int_size_in_bytes (etype), GET_MODE_SIZE (mode)))
    4175                 :          0 :     return false;
    4176                 :            : 
    4177                 :            :   return true;
    4178                 :            : }
    4179                 :            : 
    4180                 :            : /* Fold
    4181                 :            :      r = __atomic_compare_exchange_N (p, &e, d, w, s, f);
    4182                 :            :    into
    4183                 :            :      _Complex uintN_t t = ATOMIC_COMPARE_EXCHANGE (p, e, d, w * 256 + N, s, f);
    4184                 :            :      i = IMAGPART_EXPR <t>;
    4185                 :            :      r = (_Bool) i;
    4186                 :            :      e = REALPART_EXPR <t>;  */
    4187                 :            : 
    4188                 :            : void
    4189                 :       5089 : fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
    4190                 :            : {
    4191                 :       5089 :   gimple *stmt = gsi_stmt (*gsi);
    4192                 :       5089 :   tree fndecl = gimple_call_fndecl (stmt);
    4193                 :       5089 :   tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    4194                 :       5089 :   tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
    4195                 :       5089 :   tree ctype = build_complex_type (itype);
    4196                 :       5089 :   tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
    4197                 :       5089 :   bool throws = false;
    4198                 :       5089 :   edge e = NULL;
    4199                 :       5089 :   gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
    4200                 :            :                                    expected);
    4201                 :       5089 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4202                 :       5089 :   gimple_stmt_iterator gsiret = gsi_for_stmt (g);
    4203                 :       5089 :   if (!useless_type_conversion_p (itype, TREE_TYPE (expected)))
    4204                 :            :     {
    4205                 :       2457 :       g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
    4206                 :            :                                build1 (VIEW_CONVERT_EXPR, itype,
    4207                 :            :                                        gimple_assign_lhs (g)));
    4208                 :       2457 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4209                 :            :     }
    4210                 :       5089 :   int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
    4211                 :       9833 :              + int_size_in_bytes (itype);
    4212                 :       5089 :   g = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE, 6,
    4213                 :            :                                   gimple_call_arg (stmt, 0),
    4214                 :            :                                   gimple_assign_lhs (g),
    4215                 :            :                                   gimple_call_arg (stmt, 2),
    4216                 :            :                                   build_int_cst (integer_type_node, flag),
    4217                 :            :                                   gimple_call_arg (stmt, 4),
    4218                 :            :                                   gimple_call_arg (stmt, 5));
    4219                 :       5089 :   tree lhs = make_ssa_name (ctype);
    4220                 :       5089 :   gimple_call_set_lhs (g, lhs);
    4221                 :       5089 :   gimple_move_vops (g, stmt);
    4222                 :       5089 :   tree oldlhs = gimple_call_lhs (stmt);
    4223                 :       5089 :   if (stmt_can_throw_internal (cfun, stmt))
    4224                 :            :     {
    4225                 :        179 :       throws = true;
    4226                 :        179 :       e = find_fallthru_edge (gsi_bb (*gsi)->succs);
    4227                 :            :     }
    4228                 :      10178 :   gimple_call_set_nothrow (as_a <gcall *> (g),
    4229                 :       5089 :                            gimple_call_nothrow_p (as_a <gcall *> (stmt)));
    4230                 :       5089 :   gimple_call_set_lhs (stmt, NULL_TREE);
    4231                 :       5089 :   gsi_replace (gsi, g, true);
    4232                 :       5089 :   if (oldlhs)
    4233                 :            :     {
    4234                 :       5049 :       g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
    4235                 :            :                                build1 (IMAGPART_EXPR, itype, lhs));
    4236                 :       5049 :       if (throws)
    4237                 :            :         {
    4238                 :        177 :           gsi_insert_on_edge_immediate (e, g);
    4239                 :        177 :           *gsi = gsi_for_stmt (g);
    4240                 :            :         }
    4241                 :            :       else
    4242                 :       4872 :         gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4243                 :       5049 :       g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
    4244                 :       5049 :       gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4245                 :            :     }
    4246                 :       5089 :   g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
    4247                 :            :                            build1 (REALPART_EXPR, itype, lhs));
    4248                 :       5089 :   if (throws && oldlhs == NULL_TREE)
    4249                 :            :     {
    4250                 :          2 :       gsi_insert_on_edge_immediate (e, g);
    4251                 :          2 :       *gsi = gsi_for_stmt (g);
    4252                 :            :     }
    4253                 :            :   else
    4254                 :       5087 :     gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4255                 :       5089 :   if (!useless_type_conversion_p (TREE_TYPE (expected), itype))
    4256                 :            :     {
    4257                 :       4914 :       g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
    4258                 :            :                                VIEW_CONVERT_EXPR,
    4259                 :       2457 :                                build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected),
    4260                 :            :                                        gimple_assign_lhs (g)));
    4261                 :       2457 :       gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4262                 :            :     }
    4263                 :       5089 :   g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
    4264                 :       5089 :   gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4265                 :       5089 :   *gsi = gsiret;
    4266                 :       5089 : }
    4267                 :            : 
    4268                 :            : /* Return true if ARG0 CODE ARG1 in infinite signed precision operation
    4269                 :            :    doesn't fit into TYPE.  The test for overflow should be regardless of
    4270                 :            :    -fwrapv, and even for unsigned types.  */
    4271                 :            : 
    4272                 :            : bool
    4273                 :    1164870 : arith_overflowed_p (enum tree_code code, const_tree type,
    4274                 :            :                     const_tree arg0, const_tree arg1)
    4275                 :            : {
    4276                 :    1164870 :   widest2_int warg0 = widest2_int_cst (arg0);
    4277                 :    1164870 :   widest2_int warg1 = widest2_int_cst (arg1);
    4278                 :    1164870 :   widest2_int wres;
    4279                 :    1164870 :   switch (code)
    4280                 :            :     {
    4281                 :     263109 :     case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
    4282                 :     352467 :     case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
    4283                 :     549296 :     case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
    4284                 :          0 :     default: gcc_unreachable ();
    4285                 :            :     }
    4286                 :    1164870 :   signop sign = TYPE_SIGN (type);
    4287                 :    1793470 :   if (sign == UNSIGNED && wi::neg_p (wres))
    4288                 :            :     return true;
    4289                 :     934578 :   return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
    4290                 :            : }
    4291                 :            : 
    4292                 :            : /* If IFN_MASK_LOAD/STORE call CALL is unconditional, return a MEM_REF
    4293                 :            :    for the memory it references, otherwise return null.  VECTYPE is the
    4294                 :            :    type of the memory vector.  */
    4295                 :            : 
    4296                 :            : static tree
    4297                 :       1593 : gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
    4298                 :            : {
    4299                 :       1593 :   tree ptr = gimple_call_arg (call, 0);
    4300                 :       1593 :   tree alias_align = gimple_call_arg (call, 1);
    4301                 :       1593 :   tree mask = gimple_call_arg (call, 2);
    4302                 :       1593 :   if (!tree_fits_uhwi_p (alias_align) || !integer_all_onesp (mask))
    4303                 :       1579 :     return NULL_TREE;
    4304                 :            : 
    4305                 :         14 :   unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align) * BITS_PER_UNIT;
    4306                 :         14 :   if (TYPE_ALIGN (vectype) != align)
    4307                 :         14 :     vectype = build_aligned_type (vectype, align);
    4308                 :         14 :   tree offset = build_zero_cst (TREE_TYPE (alias_align));
    4309                 :         14 :   return fold_build2 (MEM_REF, vectype, ptr, offset);
    4310                 :            : }
    4311                 :            : 
    4312                 :            : /* Try to fold IFN_MASK_LOAD call CALL.  Return true on success.  */
    4313                 :            : 
    4314                 :            : static bool
    4315                 :        638 : gimple_fold_mask_load (gimple_stmt_iterator *gsi, gcall *call)
    4316                 :            : {
    4317                 :        638 :   tree lhs = gimple_call_lhs (call);
    4318                 :        638 :   if (!lhs)
    4319                 :            :     return false;
    4320                 :            : 
    4321                 :        638 :   if (tree rhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (lhs)))
    4322                 :            :     {
    4323                 :          0 :       gassign *new_stmt = gimple_build_assign (lhs, rhs);
    4324                 :          0 :       gimple_set_location (new_stmt, gimple_location (call));
    4325                 :          0 :       gimple_move_vops (new_stmt, call);
    4326                 :          0 :       gsi_replace (gsi, new_stmt, false);
    4327                 :          0 :       return true;
    4328                 :            :     }
    4329                 :            :   return false;
    4330                 :            : }
    4331                 :            : 
    4332                 :            : /* Try to fold IFN_MASK_STORE call CALL.  Return true on success.  */
    4333                 :            : 
    4334                 :            : static bool
    4335                 :        955 : gimple_fold_mask_store (gimple_stmt_iterator *gsi, gcall *call)
    4336                 :            : {
    4337                 :        955 :   tree rhs = gimple_call_arg (call, 3);
    4338                 :        955 :   if (tree lhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (rhs)))
    4339                 :            :     {
    4340                 :         14 :       gassign *new_stmt = gimple_build_assign (lhs, rhs);
    4341                 :         14 :       gimple_set_location (new_stmt, gimple_location (call));
    4342                 :         14 :       gimple_move_vops (new_stmt, call);
    4343                 :         14 :       gsi_replace (gsi, new_stmt, false);
    4344                 :         14 :       return true;
    4345                 :            :     }
    4346                 :            :   return false;
    4347                 :            : }
    4348                 :            : 
    4349                 :            : /* Attempt to fold a call statement referenced by the statement iterator GSI.
    4350                 :            :    The statement may be replaced by another statement, e.g., if the call
    4351                 :            :    simplifies to a constant value. Return true if any changes were made.
    4352                 :            :    It is assumed that the operands have been previously folded.  */
    4353                 :            : 
    4354                 :            : static bool
    4355                 :   35828800 : gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
    4356                 :            : {
    4357                 :   35828800 :   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
    4358                 :            :   tree callee;
    4359                 :            :   bool changed = false;
    4360                 :            :   unsigned i;
    4361                 :            : 
    4362                 :            :   /* Fold *& in call arguments.  */
    4363                 :  104473000 :   for (i = 0; i < gimple_call_num_args (stmt); ++i)
    4364                 :   68644300 :     if (REFERENCE_CLASS_P (gimple_call_arg (stmt, i)))
    4365                 :            :       {
    4366                 :     487146 :         tree tmp = maybe_fold_reference (gimple_call_arg (stmt, i), false);
    4367                 :     487146 :         if (tmp)
    4368                 :            :           {
    4369                 :          0 :             gimple_call_set_arg (stmt, i, tmp);
    4370                 :          0 :             changed = true;
    4371                 :            :           }
    4372                 :            :       }
    4373                 :            : 
    4374                 :            :   /* Check for virtual calls that became direct calls.  */
    4375                 :   35828800 :   callee = gimple_call_fn (stmt);
    4376                 :   35828800 :   if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
    4377                 :            :     {
    4378                 :     292503 :       if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
    4379                 :            :         {
    4380                 :         12 :           if (dump_file && virtual_method_call_p (callee)
    4381                 :        253 :               && !possible_polymorphic_call_target_p
    4382                 :         12 :                     (callee, stmt, cgraph_node::get (gimple_call_addr_fndecl
    4383                 :         12 :                                                      (OBJ_TYPE_REF_EXPR (callee)))))
    4384                 :            :             {
    4385                 :          0 :               fprintf (dump_file,
    4386                 :            :                        "Type inheritance inconsistent devirtualization of ");
    4387                 :          0 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    4388                 :          0 :               fprintf (dump_file, " to ");
    4389                 :          0 :               print_generic_expr (dump_file, callee, TDF_SLIM);
    4390                 :          0 :               fprintf (dump_file, "\n");
    4391                 :            :             }
    4392                 :            : 
    4393                 :        241 :           gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
    4394                 :        241 :           changed = true;
    4395                 :            :         }
    4396                 :     292262 :       else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
    4397                 :            :         {
    4398                 :     288538 :           bool final;
    4399                 :     288538 :           vec <cgraph_node *>targets
    4400                 :     288538 :             = possible_polymorphic_call_targets (callee, stmt, &final);
    4401                 :     288538 :           if (final && targets.length () <= 1 && dbg_cnt (devirt))
    4402                 :            :             {
    4403                 :       2251 :               tree lhs = gimple_call_lhs (stmt);
    4404                 :       2251 :               if (dump_enabled_p ())
    4405                 :            :                 {
    4406                 :         44 :                   dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
    4407                 :            :                                    "folding virtual function call to %s\n",
    4408                 :         22 :                                    targets.length () == 1
    4409                 :         22 :                                    ? targets[0]->name ()
    4410                 :            :                                    : "__builtin_unreachable");
    4411                 :            :                 }
    4412                 :       2251 :               if (targets.length () == 1)
    4413                 :            :                 {
    4414                 :       2198 :                   tree fndecl = targets[0]->decl;
    4415                 :       2198 :                   gimple_call_set_fndecl (stmt, fndecl);
    4416                 :       2198 :                   changed = true;
    4417                 :            :                   /* If changing the call to __cxa_pure_virtual
    4418                 :            :                      or similar noreturn function, adjust gimple_call_fntype
    4419                 :            :                      too.  */
    4420                 :       2198 :                   if (gimple_call_noreturn_p (stmt)
    4421                 :         24 :                       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
    4422                 :         16 :                       && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
    4423                 :       2214 :                       && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
    4424                 :         16 :                           == void_type_node))
    4425                 :         16 :                     gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
    4426                 :            :                   /* If the call becomes noreturn, remove the lhs.  */
    4427                 :       2198 :                   if (lhs
    4428                 :       1907 :                       && gimple_call_noreturn_p (stmt)
    4429                 :       2218 :                       && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
    4430                 :          8 :                           || should_remove_lhs_p (lhs)))
    4431                 :            :                     {
    4432                 :         16 :                       if (TREE_CODE (lhs) == SSA_NAME)
    4433                 :            :                         {
    4434                 :          0 :                           tree var = create_tmp_var (TREE_TYPE (lhs));
    4435                 :          0 :                           tree def = get_or_create_ssa_default_def (cfun, var);
    4436                 :          0 :                           gimple *new_stmt = gimple_build_assign (lhs, def);
    4437                 :          0 :                           gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    4438                 :            :                         }
    4439                 :         16 :                       gimple_call_set_lhs (stmt, NULL_TREE);
    4440                 :            :                     }
    4441                 :       2198 :                   maybe_remove_unused_call_args (cfun, stmt);
    4442                 :            :                 }
    4443                 :            :               else
    4444                 :            :                 {
    4445                 :         53 :                   tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
    4446                 :         53 :                   gimple *new_stmt = gimple_build_call (fndecl, 0);
    4447                 :         53 :                   gimple_set_location (new_stmt, gimple_location (stmt));
    4448                 :            :                   /* If the call had a SSA name as lhs morph that into
    4449                 :            :                      an uninitialized value.  */
    4450                 :         53 :                   if (lhs && TREE_CODE (lhs) == SSA_NAME)
    4451                 :            :                     {
    4452                 :         15 :                       tree var = create_tmp_var (TREE_TYPE (lhs));
    4453                 :         15 :                       SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
    4454                 :         15 :                       SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
    4455                 :         15 :                       set_ssa_default_def (cfun, var, lhs);
    4456                 :            :                     }
    4457                 :         53 :                   gimple_move_vops (new_stmt, stmt);
    4458                 :         53 :                   gsi_replace (gsi, new_stmt, false);
    4459                 :         53 :                   return true;
    4460                 :            :                 }
    4461                 :            :             }
    4462                 :            :         }
    4463                 :            :     }
    4464                 :            : 
    4465                 :            :   /* Check for indirect calls that became direct calls, and then
    4466                 :            :      no longer require a static chain.  */
    4467                 :   35828800 :   if (gimple_call_chain (stmt))
    4468                 :            :     {
    4469                 :     180218 :       tree fn = gimple_call_fndecl (stmt);
    4470                 :     208461 :       if (fn && !DECL_STATIC_CHAIN (fn))
    4471                 :            :         {
    4472                 :       1729 :           gimple_call_set_chain (stmt, NULL);
    4473                 :       1729 :           changed = true;
    4474                 :            :         }
    4475                 :            :       else
    4476                 :            :         {
    4477                 :     178489 :           tree tmp = maybe_fold_reference (gimple_call_chain (stmt), false);
    4478                 :     178489 :           if (tmp)
    4479                 :            :             {
    4480                 :          0 :               gimple_call_set_chain (stmt, tmp);
    4481                 :          0 :               changed = true;
    4482                 :            :             }
    4483                 :            :         }
    4484                 :            :     }
    4485                 :            : 
    4486                 :   35828800 :   if (inplace)
    4487                 :            :     return changed;
    4488                 :            : 
    4489                 :            :   /* Check for builtins that CCP can handle using information not
    4490                 :            :      available in the generic fold routines.  */
    4491                 :   35827600 :   if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    4492                 :            :     {
    4493                 :    7200390 :       if (gimple_fold_builtin (gsi))
    4494                 :      84977 :         changed = true;
    4495                 :            :     }
    4496                 :   28627200 :   else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
    4497                 :            :     {
    4498                 :     900127 :         changed |= targetm.gimple_fold_builtin (gsi);
    4499                 :            :     }
    4500                 :   27727100 :   else if (gimple_call_internal_p (stmt))
    4501                 :            :     {
    4502                 :    1106980 :       enum tree_code subcode = ERROR_MARK;
    4503                 :    1106980 :       tree result = NULL_TREE;
    4504                 :    1106980 :       bool cplx_result = false;
    4505                 :    1106980 :       tree overflow = NULL_TREE;
    4506                 :    1106980 :       switch (gimple_call_internal_fn (stmt))
    4507                 :            :         {
    4508                 :      94394 :         case IFN_BUILTIN_EXPECT:
    4509                 :      94394 :           result = fold_builtin_expect (gimple_location (stmt),
    4510                 :            :                                         gimple_call_arg (stmt, 0),
    4511                 :            :                                         gimple_call_arg (stmt, 1),
    4512                 :            :                                         gimple_call_arg (stmt, 2),
    4513                 :            :                                         NULL_TREE);
    4514                 :      94394 :           break;
    4515                 :      18103 :         case IFN_UBSAN_OBJECT_SIZE:
    4516                 :      18103 :           {
    4517                 :      18103 :             tree offset = gimple_call_arg (stmt, 1);
    4518                 :      18103 :             tree objsize = gimple_call_arg (stmt, 2);
    4519                 :      18103 :             if (integer_all_onesp (objsize)
    4520                 :      18103 :                 || (TREE_CODE (offset) == INTEGER_CST
    4521                 :       7359 :                     && TREE_CODE (objsize) == INTEGER_CST
    4522                 :       1088 :                     && tree_int_cst_le (offset, objsize)))
    4523                 :            :               {
    4524                 :       1940 :                 replace_call_with_value (gsi, NULL_TREE);
    4525                 :       1940 :                 return true;
    4526                 :            :               }
    4527                 :            :           }
    4528                 :            :           break;
    4529                 :      13505 :         case IFN_UBSAN_PTR:
    4530                 :      13505 :           if (integer_zerop (gimple_call_arg (stmt, 1)))
    4531                 :            :             {
    4532                 :         49 :               replace_call_with_value (gsi, NULL_TREE);
    4533                 :         49 :               return true;
    4534                 :            :             }
    4535                 :            :           break;
    4536                 :       7633 :         case IFN_UBSAN_BOUNDS:
    4537                 :       7633 :           {
    4538                 :       7633 :             tree index = gimple_call_arg (stmt, 1);
    4539                 :       7633 :             tree bound = gimple_call_arg (stmt, 2);
    4540                 :       7633 :             if (TREE_CODE (index) == INTEGER_CST
    4541                 :       4876 :                 && TREE_CODE (bound) == INTEGER_CST)
    4542                 :            :               {
    4543                 :       4736 :                 index = fold_convert (TREE_TYPE (bound), index);
    4544                 :       4736 :                 if (TREE_CODE (index) == INTEGER_CST
    4545                 :       4736 :                     && tree_int_cst_le (index, bound))
    4546                 :            :                   {
    4547                 :        269 :                     replace_call_with_value (gsi, NULL_TREE);
    4548                 :        269 :                     return true;
    4549                 :            :                   }
    4550                 :            :               }
    4551                 :            :           }
    4552                 :            :           break;
    4553                 :      16610 :         case IFN_GOACC_DIM_SIZE:
    4554                 :      16610 :         case IFN_GOACC_DIM_POS:
    4555                 :      16610 :           result = fold_internal_goacc_dim (stmt);
    4556                 :      16610 :           break;
    4557                 :      10939 :         case IFN_UBSAN_CHECK_ADD:
    4558                 :      10939 :           subcode = PLUS_EXPR;
    4559                 :      10939 :           break;
    4560                 :      11095 :         case IFN_UBSAN_CHECK_SUB:
    4561                 :      11095 :           subcode = MINUS_EXPR;
    4562                 :      11095 :           break;
    4563                 :       9541 :         case IFN_UBSAN_CHECK_MUL:
    4564                 :       9541 :           subcode = MULT_EXPR;
    4565                 :       9541 :           break;
    4566                 :     107731 :         case IFN_ADD_OVERFLOW:
    4567                 :     107731 :           subcode = PLUS_EXPR;
    4568                 :     107731 :           cplx_result = true;
    4569                 :     107731 :           break;
    4570                 :     146502 :         case IFN_SUB_OVERFLOW:
    4571                 :     146502 :           subcode = MINUS_EXPR;
    4572                 :     146502 :           cplx_result = true;
    4573                 :     146502 :           break;
    4574                 :     152510 :         case IFN_MUL_OVERFLOW:
    4575                 :     152510 :           subcode = MULT_EXPR;
    4576                 :     152510 :           cplx_result = true;
    4577                 :     152510 :           break;
    4578                 :        638 :         case IFN_MASK_LOAD:
    4579                 :        638 :           changed |= gimple_fold_mask_load (gsi, stmt);
    4580                 :        638 :           break;
    4581                 :        955 :         case IFN_MASK_STORE:
    4582                 :        955 :           changed |= gimple_fold_mask_store (gsi, stmt);
    4583                 :        955 :           break;
    4584                 :            :         default:
    4585                 :            :           break;
    4586                 :            :         }
    4587                 :    1104720 :       if (subcode != ERROR_MARK)
    4588                 :            :         {
    4589                 :     438318 :           tree arg0 = gimple_call_arg (stmt, 0);
    4590                 :     438318 :           tree arg1 = gimple_call_arg (stmt, 1);
    4591                 :     438318 :           tree type = TREE_TYPE (arg0);
    4592                 :     438318 :           if (cplx_result)
    4593                 :            :             {
    4594                 :     406743 :               tree lhs = gimple_call_lhs (stmt);
    4595                 :     406743 :               if (lhs == NULL_TREE)
    4596                 :            :                 type = NULL_TREE;
    4597                 :            :               else
    4598                 :     406743 :                 type = TREE_TYPE (TREE_TYPE (lhs));
    4599                 :            :             }
    4600                 :     438318 :           if (type == NULL_TREE)
    4601                 :            :             ;
    4602                 :            :           /* x = y + 0; x = y - 0; x = y * 0; */
    4603                 :     438318 :           else if (integer_zerop (arg1))
    4604                 :       8727 :             result = subcode == MULT_EXPR ? integer_zero_node : arg0;
    4605                 :            :           /* x = 0 + y; x = 0 * y; */
    4606                 :     429591 :           else if (subcode != MINUS_EXPR && integer_zerop (arg0))
    4607                 :       2162 :             result = subcode == MULT_EXPR ? integer_zero_node : arg1;
    4608                 :            :           /* x = y - y; */
    4609                 :     427429 :           else if (subcode == MINUS_EXPR && operand_equal_p (arg0, arg1, 0))
    4610                 :        283 :             result = integer_zero_node;
    4611                 :            :           /* x = y * 1; x = 1 * y; */
    4612                 :     427146 :           else if (subcode == MULT_EXPR && integer_onep (arg1))
    4613                 :            :             result = arg0;
    4614                 :     424619 :           else if (subcode == MULT_EXPR && integer_onep (arg0))
    4615                 :            :             result = arg1;
    4616                 :     423868 :           else if (TREE_CODE (arg0) == INTEGER_CST
    4617                 :     144723 :                    && TREE_CODE (arg1) == INTEGER_CST)
    4618                 :            :             {
    4619                 :      10225 :               if (cplx_result)
    4620                 :       9671 :                 result = int_const_binop (subcode, fold_convert (type, arg0),
    4621                 :       9671 :                                           fold_convert (type, arg1));
    4622                 :            :               else
    4623                 :        554 :                 result = int_const_binop (subcode, arg0, arg1);
    4624                 :      10225 :               if (result && arith_overflowed_p (subcode, type, arg0, arg1))
    4625                 :            :                 {
    4626                 :       5740 :                   if (cplx_result)
    4627                 :       5206 :                     overflow = build_one_cst (type);
    4628                 :            :                   else
    4629                 :            :                     result = NULL_TREE;
    4630                 :            :                 }
    4631                 :            :             }
    4632                 :     437784 :           if (result)
    4633                 :            :             {
    4634                 :      24141 :               if (result == integer_zero_node)
    4635                 :       3010 :                 result = build_zero_cst (type);
    4636                 :      42230 :               else if (cplx_result && TREE_TYPE (result) != type)
    4637                 :            :                 {
    4638                 :       9816 :                   if (TREE_CODE (result) == INTEGER_CST)
    4639                 :            :                     {
    4640                 :        748 :                       if (arith_overflowed_p (PLUS_EXPR, type, result,
    4641                 :            :                                               integer_zero_node))
    4642                 :        661 :                         overflow = build_one_cst (type);
    4643                 :            :                     }
    4644                 :       9068 :                   else if ((!TYPE_UNSIGNED (TREE_TYPE (result))
    4645                 :       7084 :                             && TYPE_UNSIGNED (type))
    4646                 :      11672 :                            || (TYPE_PRECISION (type)
    4647                 :       2604 :                                < (TYPE_PRECISION (TREE_TYPE (result))
    4648                 :       5208 :                                   + (TYPE_UNSIGNED (TREE_TYPE (result))
    4649                 :       2604 :                                      && !TYPE_UNSIGNED (type)))))
    4650                 :            :                     result = NULL_TREE;
    4651                 :        748 :                   if (result)
    4652                 :        748 :                     result = fold_convert (type, result);
    4653                 :            :                 }
    4654                 :            :             }
    4655                 :            :         }
    4656                 :            : 
    4657                 :    1104720 :       if (result)
    4658                 :            :         {
    4659                 :      62383 :           if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
    4660                 :       3025 :             result = drop_tree_overflow (result);
    4661                 :      31743 :           if (cplx_result)
    4662                 :            :             {
    4663                 :      15041 :               if (overflow == NULL_TREE)
    4664                 :       9174 :                 overflow = build_zero_cst (TREE_TYPE (result));
    4665                 :      15041 :               tree ctype = build_complex_type (TREE_TYPE (result));
    4666                 :      15041 :               if (TREE_CODE (result) == INTEGER_CST
    4667                 :      13938 :                   && TREE_CODE (overflow) == INTEGER_CST)
    4668                 :      13938 :                 result = build_complex (ctype, result, overflow);
    4669                 :            :               else
    4670                 :       1103 :                 result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
    4671                 :            :                                      ctype, result, overflow);
    4672                 :            :             }
    4673                 :      31743 :           if (!update_call_from_tree (gsi, result))
    4674                 :          0 :             gimplify_and_update_call_from_tree (gsi, result);
    4675                 :            :           changed = true;
    4676                 :            :         }
    4677                 :            :     }
    4678                 :            : 
    4679                 :            :   return changed;
    4680                 :            : }
    4681                 :            : 
    4682                 :            : 
    4683                 :            : /* Return true whether NAME has a use on STMT.  */
    4684                 :            : 
    4685                 :            : static bool
    4686                 :       1310 : has_use_on_stmt (tree name, gimple *stmt)
    4687                 :            : {
    4688                 :       1310 :   imm_use_iterator iter;
    4689                 :       1310 :   use_operand_p use_p;
    4690                 :       4503 :   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    4691                 :       3235 :     if (USE_STMT (use_p) == stmt)
    4692                 :            :       return true;
    4693                 :            :   return false;
    4694                 :            : }
    4695                 :            : 
    4696                 :            : /* Worker for fold_stmt_1 dispatch to pattern based folding with
    4697                 :            :    gimple_simplify.
    4698                 :            : 
    4699                 :            :    Replaces *GSI with the simplification result in RCODE and OPS
    4700                 :            :    and the associated statements in *SEQ.  Does the replacement
    4701                 :            :    according to INPLACE and returns true if the operation succeeded.  */
    4702                 :            : 
    4703                 :            : static bool
    4704                 :    5771770 : replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
    4705                 :            :                                   gimple_match_op *res_op,
    4706                 :            :                                   gimple_seq *seq, bool inplace)
    4707                 :            : {
    4708                 :    5771770 :   gimple *stmt = gsi_stmt (*gsi);
    4709                 :    5771770 :   tree *ops = res_op->ops;
    4710                 :    5771770 :   unsigned int num_ops = res_op->num_ops;
    4711                 :            : 
    4712                 :            :   /* Play safe and do not allow abnormals to be mentioned in
    4713                 :            :      newly created statements.  See also maybe_push_res_to_seq.
    4714                 :            :      As an exception allow such uses if there was a use of the
    4715                 :            :      same SSA name on the old stmt.  */
    4716                 :   12125100 :   for (unsigned int i = 0; i < num_ops; ++i)
    4717                 :    6354580 :     if (TREE_CODE (ops[i]) == SSA_NAME
    4718                 :    4314740 :         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i])
    4719                 :    6355890 :         && !has_use_on_stmt (ops[i], stmt))
    4720                 :            :       return false;
    4721                 :            : 
    4722                 :    5770500 :   if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
    4723                 :      25090 :     for (unsigned int i = 0; i < 2; ++i)
    4724                 :      16727 :       if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
    4725                 :      14006 :           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i))
    4726                 :      16728 :           && !has_use_on_stmt (TREE_OPERAND (ops[0], i), stmt))
    4727                 :            :         return false;
    4728                 :            : 
    4729                 :            :   /* Don't insert new statements when INPLACE is true, even if we could
    4730                 :            :      reuse STMT for the final statement.  */
    4731                 :    5770500 :   if (inplace && !gimple_seq_empty_p (*seq))
    4732                 :            :     return false;
    4733                 :            : 
    4734                 :    5770500 :   if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
    4735                 :            :     {
    4736                 :    4688450 :       gcc_assert (res_op->code.is_tree_code ());
    4737                 :    4688450 :       if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
    4738                 :            :           /* GIMPLE_CONDs condition may not throw.  */
    4739                 :    4688450 :           && (!flag_exceptions
    4740                 :     125337 :               || !cfun->can_throw_non_call_exceptions
    4741                 :      59807 :               || !operation_could_trap_p (res_op->code,
    4742                 :      59807 :                                           FLOAT_TYPE_P (TREE_TYPE (ops[0])),
    4743                 :            :                                           false, NULL_TREE)))
    4744                 :     264588 :         gimple_cond_set_condition (cond_stmt, res_op->code, ops[0], ops[1]);
    4745                 :    4423860 :       else if (res_op->code == SSA_NAME)
    4746                 :    3426640 :         gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
    4747                 :    3426640 :                                    build_zero_cst (TREE_TYPE (ops[0])));
    4748                 :     997227 :       else if (res_op->code == INTEGER_CST)
    4749                 :            :         {
    4750                 :     656492 :           if (integer_zerop (ops[0]))
    4751                 :     400506 :             gimple_cond_make_false (cond_stmt);
    4752                 :            :           else
    4753                 :     255986 :             gimple_cond_make_true (cond_stmt);
    4754                 :            :         }
    4755                 :     340735 :       else if (!inplace)
    4756                 :            :         {
    4757                 :     340735 :           tree res = maybe_push_res_to_seq (res_op, seq);
    4758                 :     340735 :           if (!res)
    4759                 :            :             return false;
    4760                 :     681470 :           gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
    4761                 :     340735 :                                      build_zero_cst (TREE_TYPE (res)));
    4762                 :            :         }
    4763                 :            :       else
    4764                 :            :         return false;
    4765                 :    4688450 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4766                 :            :         {
    4767                 :        747 :           fprintf (dump_file, "gimple_simplified to ");
    4768                 :        747 :           if (!gimple_seq_empty_p (*seq))
    4769                 :          0 :             print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
    4770                 :        747 :           print_gimple_stmt (dump_file, gsi_stmt (*gsi),
    4771                 :            :                              0, TDF_SLIM);
    4772                 :            :         }
    4773                 :    4688450 :       gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
    4774                 :    4688450 :       return true;
    4775                 :            :     }
    4776                 :    1082050 :   else if (is_gimple_assign (stmt)
    4777                 :    1082050 :            && res_op->code.is_tree_code ())
    4778                 :            :     {
    4779                 :    1053320 :       if (!inplace
    4780                 :    1053320 :           || gimple_num_ops (stmt) > get_gimple_rhs_num_ops (res_op->code))
    4781                 :            :         {
    4782                 :    1053320 :           maybe_build_generic_op (res_op);
    4783                 :    2403770 :           gimple_assign_set_rhs_with_ops (gsi, res_op->code,
    4784                 :            :                                           res_op->op_or_null (0),
    4785                 :            :                                           res_op->op_or_null (1),
    4786                 :            :                                           res_op->op_or_null (2));
    4787                 :    1053320 :           if (dump_file && (dump_flags & TDF_DETAILS))
    4788                 :            :             {
    4789                 :       1150 :               fprintf (dump_file, "gimple_simplified to ");
    4790                 :       1150 :               if (!gimple_seq_empty_p (*seq))
    4791                 :         21 :                 print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
    4792                 :       1150 :               print_gimple_stmt (dump_file, gsi_stmt (*gsi),
    4793                 :            :                                  0, TDF_SLIM);
    4794                 :            :             }
    4795                 :    1053320 :           gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
    4796                 :    1053320 :           return true;
    4797                 :            :         }
    4798                 :            :     }
    4799                 :      28730 :   else if (res_op->code.is_fn_code ()
    4800                 :      28730 :            && gimple_call_combined_fn (stmt) == res_op->code)
    4801                 :            :     {
    4802                 :        384 :       gcc_assert (num_ops == gimple_call_num_args (stmt));
    4803                 :       1012 :       for (unsigned int i = 0; i < num_ops; ++i)
    4804                 :        628 :         gimple_call_set_arg (stmt, i, ops[i]);
    4805                 :        384 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4806                 :            :         {
    4807                 :          0 :           fprintf (dump_file, "gimple_simplified to ");
    4808                 :          0 :           if (!gimple_seq_empty_p (*seq))
    4809                 :          0 :             print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
    4810                 :          0 :           print_gimple_stmt (dump_file, gsi_stmt (*gsi), 0, TDF_SLIM);
    4811                 :            :         }
    4812                 :        384 :       gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
    4813                 :        384 :       return true;
    4814                 :            :     }
    4815                 :      28346 :   else if (!inplace)
    4816                 :            :     {
    4817                 :      56629 :       if (gimple_has_lhs (stmt))
    4818                 :            :         {
    4819                 :      28346 :           tree lhs = gimple_get_lhs (stmt);
    4820                 :      28346 :           if (!maybe_push_res_to_seq (res_op, seq, lhs))
    4821                 :            :             return false;
    4822                 :      27907 :           if (dump_file && (dump_flags & TDF_DETAILS))
    4823                 :            :             {
    4824                 :          7 :               fprintf (dump_file, "gimple_simplified to ");
    4825                 :          7 :               print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
    4826                 :            :             }
    4827                 :      27907 :           gsi_replace_with_seq_vops (gsi, *seq);
    4828                 :      27907 :           return true;
    4829                 :            :         }
    4830                 :            :       else
    4831                 :          0 :         gcc_unreachable ();
    4832                 :            :     }
    4833                 :            : 
    4834                 :            :   return false;
    4835                 :            : }
    4836                 :            : 
    4837                 :            : /* Canonicalize MEM_REFs invariant address operand after propagation.  */
    4838                 :            : 
    4839                 :            : static bool
    4840                 :  118655000 : maybe_canonicalize_mem_ref_addr (tree *t)
    4841                 :            : {
    4842                 :  118655000 :   bool res = false;
    4843                 :            : 
    4844                 :  118655000 :   if (TREE_CODE (*t) == ADDR_EXPR)
    4845                 :   35093900 :     t = &TREE_OPERAND (*t, 0);
    4846                 :            : 
    4847                 :            :   /* The C and C++ frontends use an ARRAY_REF for indexing with their
    4848                 :            :      generic vector extension.  The actual vector referenced is
    4849                 :            :      view-converted to an array type for this purpose.  If the index
    4850                 :            :      is constant the canonical representation in the middle-end is a
    4851                 :            :      BIT_FIELD_REF so re-write the former to the latter here.  */
    4852                 :  118655000 :   if (TREE_CODE (*t) == ARRAY_REF
    4853                 :    7584540 :       && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
    4854                 :      82153 :       && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
    4855                 :  118666000 :       && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
    4856                 :            :     {
    4857                 :      10689 :       tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
    4858                 :      10689 :       if (VECTOR_TYPE_P (vtype))
    4859                 :            :         {
    4860                 :      10689 :           tree low = array_ref_low_bound (*t);
    4861                 :      10689 :           if (TREE_CODE (low) == INTEGER_CST)
    4862                 :            :             {
    4863                 :      10689 :               if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
    4864                 :            :                 {
    4865                 :      21332 :                   widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
    4866                 :      21332 :                                             wi::to_widest (low));
    4867                 :      21332 :                   idx = wi::mul (idx, wi::to_widest
    4868                 :      10666 :                                          (TYPE_SIZE (TREE_TYPE (*t))));
    4869                 :      10666 :                   widest_int ext
    4870                 :      10666 :                     = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
    4871                 :      10666 :                   if (wi::les_p (ext, wi::to_widest (TYPE_SIZE (vtype))))
    4872                 :            :                     {
    4873                 :      20702 :                       *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
    4874                 :      10351 :                                        TREE_TYPE (*t),
    4875                 :      10351 :                                        TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
    4876                 :      10351 :                                        TYPE_SIZE (TREE_TYPE (*t)),
    4877                 :            :                                        wide_int_to_tree (bitsizetype, idx));
    4878                 :      10351 :                       res = true;
    4879                 :            :                     }
    4880                 :            :                 }
    4881                 :            :             }
    4882                 :            :         }
    4883                 :            :     }
    4884                 :            : 
    4885                 :  228628000 :   while (handled_component_p (*t))
    4886                 :  109973000 :     t = &TREE_OPERAND (*t, 0);
    4887                 :            : 
    4888                 :            :   /* Canonicalize MEM [&foo.bar, 0] which appears after propagating
    4889                 :            :      of invariant addresses into a SSA name MEM_REF address.  */
    4890                 :  118655000 :   if (TREE_CODE (*t) == MEM_REF
    4891                 :  118655000 :       || TREE_CODE (*t) == TARGET_MEM_REF)
    4892                 :            :     {
    4893                 :   60238200 :       tree addr = TREE_OPERAND (*t, 0);
    4894                 :   60238200 :       if (TREE_CODE (addr) == ADDR_EXPR
    4895                 :   60238200 :           && (TREE_CODE (TREE_OPERAND (addr, 0)) == MEM_REF
    4896                 :   17430000 :               || handled_component_p (TREE_OPERAND (addr, 0))))
    4897                 :            :         {
    4898                 :     310216 :           tree base;
    4899                 :     310216 :           poly_int64 coffset;
    4900                 :     310216 :           base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
    4901                 :            :                                                 &coffset);
    4902                 :     310216 :           if (!base)
    4903                 :          0 :             gcc_unreachable ();
    4904                 :            : 
    4905                 :     310216 :           TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
    4906                 :     310216 :           TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
    4907                 :     310216 :                                                   TREE_OPERAND (*t, 1),
    4908                 :     310216 :                                                   size_int (coffset));
    4909                 :     310216 :           res = true;
    4910                 :            :         }
    4911                 :   60238200 :       gcc_checking_assert (TREE_CODE (TREE_OPERAND (*t, 0)) == DEBUG_EXPR_DECL
    4912                 :            :                            || is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)));
    4913                 :            :     }
    4914                 :            : 
    4915                 :            :   /* Canonicalize back MEM_REFs to plain reference trees if the object
    4916                 :            :      accessed is a decl that has the same access semantics as the MEM_REF.  */
    4917                 :  118655000 :   if (TREE_CODE (*t) == MEM_REF
    4918                 :   59072200 :       && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
    4919                 :   17235800 :       && integer_zerop (TREE_OPERAND (*t, 1))
    4920                 :  128276000 :       && MR_DEPENDENCE_CLIQUE (*t) == 0)
    4921                 :            :     {
    4922                 :    6015460 :       tree decl = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
    4923                 :    6015460 :       tree alias_type = TREE_TYPE (TREE_OPERAND (*t, 1));
    4924                 :    6015460 :       if (/* Same volatile qualification.  */
    4925                 :    6015460 :           TREE_THIS_VOLATILE (*t) == TREE_THIS_VOLATILE (decl)
    4926                 :            :           /* Same TBAA behavior with -fstrict-aliasing.  */
    4927                 :    5992400 :           && !TYPE_REF_CAN_ALIAS_ALL (alias_type)
    4928                 :    5824650 :           && (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
    4929                 :    5824650 :               == TYPE_MAIN_VARIANT (TREE_TYPE (alias_type)))
    4930                 :            :           /* Same alignment.  */
    4931                 :    1915180 :           && TYPE_ALIGN (TREE_TYPE (decl)) == TYPE_ALIGN (TREE_TYPE (*t))
    4932                 :            :           /* We have to look out here to not drop a required conversion
    4933                 :            :              from the rhs to the lhs if *t appears on the lhs or vice-versa
    4934                 :            :              if it appears on the rhs.  Thus require strict type
    4935                 :            :              compatibility.  */
    4936                 :    7902400 :           && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (decl)))
    4937                 :            :         {
    4938                 :    1120080 :           *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
    4939                 :    1120080 :           res = true;
    4940                 :            :         }
    4941                 :            :     }
    4942                 :            : 
    4943                 :            :   /* Canonicalize TARGET_MEM_REF in particular with respect to
    4944                 :            :      the indexes becoming constant.  */
    4945                 :  112640000 :   else if (TREE_CODE (*t) == TARGET_MEM_REF)
    4946                 :            :     {
    4947                 :    1166010 :       tree tem = maybe_fold_tmr (*t);
    4948                 :    1166010 :       if (tem)
    4949                 :            :         {
    4950                 :        247 :           *t = tem;
    4951                 :        247 :           res = true;
    4952                 :            :         }
    4953                 :            :     }
    4954                 :            : 
    4955                 :  118655000 :   return res;
    4956                 :            : }
    4957                 :            : 
    4958                 :            : /* Worker for both fold_stmt and fold_stmt_inplace.  The INPLACE argument
    4959                 :            :    distinguishes both cases.  */
    4960                 :            : 
    4961                 :            : static bool
    4962                 :  478004000 : fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
    4963                 :            : {
    4964                 :  478004000 :   bool changed = false;
    4965                 :  478004000 :   gimple *stmt = gsi_stmt (*gsi);
    4966                 :  478004000 :   bool nowarning = gimple_no_warning_p (stmt);
    4967                 :  478004000 :   unsigned i;
    4968                 :  478004000 :   fold_defer_overflow_warnings ();
    4969                 :            : 
    4970                 :            :   /* First do required canonicalization of [TARGET_]MEM_REF addresses
    4971                 :            :      after propagation.
    4972                 :            :      ???  This shouldn't be done in generic folding but in the
    4973                 :            :      propagation helpers which also know whether an address was
    4974                 :            :      propagated.
    4975                 :            :      Also canonicalize operand order.  */
    4976                 :  478004000 :   switch (gimple_code (stmt))
    4977                 :            :     {
    4978                 :  166357000 :     case GIMPLE_ASSIGN:
    4979                 :  166357000 :       if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
    4980                 :            :         {
    4981                 :  115086000 :           tree *rhs = gimple_assign_rhs1_ptr (stmt);
    4982                 :  115086000 :           if ((REFERENCE_CLASS_P (*rhs)
    4983                 :   76914100 :                || TREE_CODE (*rhs) == ADDR_EXPR)
    4984                 :  125464000 :               && maybe_canonicalize_mem_ref_addr (rhs))
    4985                 :            :             changed = true;
    4986                 :  115086000 :           tree *lhs = gimple_assign_lhs_ptr (stmt);
    4987                 :  115086000 :           if (REFERENCE_CLASS_P (*lhs)
    4988                 :  115086000 :               && maybe_canonicalize_mem_ref_addr (lhs))
    4989                 :            :             changed = true;
    4990                 :            :         }
    4991                 :            :       else
    4992                 :            :         {
    4993                 :            :           /* Canonicalize operand order.  */
    4994                 :   51270900 :           enum tree_code code = gimple_assign_rhs_code (stmt);
    4995                 :   51270900 :           if (TREE_CODE_CLASS (code) == tcc_comparison
    4996                 :   47204900 :               || commutative_tree_code (code)
    4997                 :   77559800 :               || commutative_ternary_tree_code (code))
    4998                 :            :             {
    4999                 :   24982100 :               tree rhs1 = gimple_assign_rhs1 (stmt);
    5000                 :   24982100 :               tree rhs2 = gimple_assign_rhs2 (stmt);
    5001                 :   24982100 :               if (tree_swap_operands_p (rhs1, rhs2))
    5002                 :            :                 {
    5003                 :    1774740 :                   gimple_assign_set_rhs1 (stmt, rhs2);
    5004                 :    1774740 :                   gimple_assign_set_rhs2 (stmt, rhs1);
    5005                 :    1774740 :                   if (TREE_CODE_CLASS (code) == tcc_comparison)
    5006                 :     227448 :                     gimple_assign_set_rhs_code (stmt,
    5007                 :            :                                                 swap_tree_comparison (code));
    5008                 :            :                   changed = true;
    5009                 :            :                 }
    5010                 :            :             }
    5011                 :            :         }
    5012                 :            :       break;
    5013                 :            :     case GIMPLE_CALL:
    5014                 :            :       {
    5015                 :  104513000 :         for (i = 0; i < gimple_call_num_args (stmt); ++i)
    5016                 :            :           {
    5017                 :   68665700 :             tree *arg = gimple_call_arg_ptr (stmt, i);
    5018                 :   68665700 :             if (REFERENCE_CLASS_P (*arg)
    5019                 :   68665700 :                 && maybe_canonicalize_mem_ref_addr (arg))
    5020                 :            :               changed = true;
    5021                 :            :           }
    5022                 :   35846900 :         tree *lhs = gimple_call_lhs_ptr (stmt);
    5023                 :   35846900 :         if (*lhs
    5024                 :   14634100 :             && REFERENCE_CLASS_P (*lhs)
    5025                 :   35904400 :             && maybe_canonicalize_mem_ref_addr (lhs))
    5026                 :            :           changed = true;
    5027                 :            :         break;
    5028                 :            :       }
    5029                 :     522199 :     case GIMPLE_ASM:
    5030                 :     522199 :       {
    5031                 :     522199 :         gasm *asm_stmt = as_a <gasm *> (stmt);
    5032                 :    1197390 :         for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
    5033                 :            :           {
    5034                 :     675191 :             tree link = gimple_asm_output_op (asm_stmt, i);
    5035                 :     675191 :             tree op = TREE_VALUE (link);
    5036                 :     675191 :             if (REFERENCE_CLASS_P (op)
    5037                 :     675191 :                 && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
    5038                 :            :               changed = true;
    5039                 :            :           }
    5040                 :     873459 :         for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
    5041                 :            :           {
    5042                 :     351260 :             tree link = gimple_asm_input_op (asm_stmt, i);
    5043                 :     351260 :             tree op = TREE_VALUE (link);
    5044                 :     351260 :             if ((REFERENCE_CLASS_P (op)
    5045                 :     347466 :                  || TREE_CODE (op) == ADDR_EXPR)
    5046                 :     382420 :                 && maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
    5047                 :            :               changed = true;
    5048                 :            :           }
    5049                 :            :       }
    5050                 :            :       break;
    5051                 :  236132000 :     case GIMPLE_DEBUG:
    5052                 :  236132000 :       if (gimple_debug_bind_p (stmt))
    5053                 :            :         {
    5054                 :  175453000 :           tree *val = gimple_debug_bind_get_value_ptr (stmt);
    5055                 :  175453000 :           if (*val
    5056                 :   96797600 :               && (REFERENCE_CLASS_P (*val)
    5057                 :   95864500 :                   || TREE_CODE (*val) == ADDR_EXPR)
    5058                 :  201071000 :               && maybe_canonicalize_mem_ref_addr (val))
    5059                 :            :             changed = true;
    5060                 :            :         }
    5061                 :            :       break;
    5062                 :   26521800 :     case GIMPLE_COND:
    5063                 :   26521800 :       {
    5064                 :            :         /* Canonicalize operand order.  */
    5065                 :   26521800 :         tree lhs = gimple_cond_lhs (stmt);
    5066                 :   26521800 :         tree rhs = gimple_cond_rhs (stmt);
    5067                 :   26521800 :         if (tree_swap_operands_p (lhs, rhs))
    5068                 :            :           {
    5069                 :    1048440 :             gcond *gc = as_a <gcond *> (stmt);
    5070                 :    1048440 :             gimple_cond_set_lhs (gc, rhs);
    5071                 :    1048440 :             gimple_cond_set_rhs (gc, lhs);
    5072                 :    1048440 :             gimple_cond_set_code (gc,
    5073                 :            :                                   swap_tree_comparison (gimple_cond_code (gc)));
    5074                 :    1048440 :             changed = true;
    5075                 :            :           }
    5076                 :            :       }
    5077                 :  478004000 :     default:;
    5078                 :            :     }
    5079                 :            : 
    5080                 :            :   /* Dispatch to pattern-based folding.  */
    5081                 :  478004000 :   if (!inplace
    5082                 :    1856280 :       || is_gimple_assign (stmt)
    5083                 :  478155000 :       || gimple_code (stmt) == GIMPLE_COND)
    5084                 :            :     {
    5085                 :  477852000 :       gimple_seq seq = NULL;
    5086                 :  477852000 :       gimple_match_op res_op;
    5087                 :  954000000 :       if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
    5088                 :            :                            valueize, valueize))
    5089                 :            :         {
    5090                 :    5771770 :           if (replace_stmt_with_simplification (gsi, &res_op, &seq, inplace))
    5091                 :            :             changed = true;
    5092                 :            :           else
    5093                 :       1707 :             gimple_seq_discard (seq);
    5094                 :            :         }
    5095                 :            :     }
    5096                 :            : 
    5097                 :  478004000 :   stmt = gsi_stmt (*gsi);
    5098                 :            : 
    5099                 :            :   /* Fold the main computation performed by the statement.  */
    5100                 :  478004000 :   switch (gimple_code (stmt))
    5101                 :            :     {
    5102                 :  166375000 :     case GIMPLE_ASSIGN:
    5103                 :  166375000 :       {
    5104                 :            :         /* Try to canonicalize for boolean-typed X the comparisons
    5105                 :            :            X == 0, X == 1, X != 0, and X != 1.  */
    5106                 :  166375000 :         if (gimple_assign_rhs_code (stmt) == EQ_EXPR
    5107                 :  166375000 :             || gimple_assign_rhs_code (stmt) == NE_EXPR)
    5108                 :            :           {
    5109                 :    2051670 :             tree lhs = gimple_assign_lhs (stmt);
    5110                 :    2051670 :             tree op1 = gimple_assign_rhs1 (stmt);
    5111                 :    2051670 :             tree op2 = gimple_assign_rhs2 (stmt);
    5112                 :    2051670 :             tree type = TREE_TYPE (op1);
    5113                 :            : 
    5114                 :            :             /* Check whether the comparison operands are of the same boolean
    5115                 :            :                type as the result type is.
    5116                 :            :                Check that second operand is an integer-constant with value
    5117                 :            :                one or zero.  */
    5118                 :    2051670 :             if (TREE_CODE (op2) == INTEGER_CST
    5119                 :    1420680 :                 && (integer_zerop (op2) || integer_onep (op2))
    5120                 :    3122860 :                 && useless_type_conversion_p (TREE_TYPE (lhs), type))
    5121                 :            :               {
    5122                 :       5725 :                 enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
    5123                 :       5725 :                 bool is_logical_not = false;
    5124                 :            : 
    5125                 :            :                 /* X == 0 and X != 1 is a logical-not.of X
    5126                 :            :                    X == 1 and X != 0 is X  */
    5127                 :       5360 :                 if ((cmp_code == EQ_EXPR && integer_zerop (op2))
    5128                 :       5725 :                     || (cmp_code == NE_EXPR && integer_onep (op2)))
    5129                 :       5699 :                   is_logical_not = true;
    5130                 :            : 
    5131                 :       5725 :                 if (is_logical_not == false)
    5132                 :         26 :                   gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1);
    5133                 :            :                 /* Only for one-bit precision typed X the transformation
    5134                 :            :                    !X -> ~X is valied.  */
    5135                 :       5699 :                 else if (TYPE_PRECISION (type) == 1)
    5136                 :       5699 :                   gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1);
    5137                 :            :                 /* Otherwise we use !X -> X ^ 1.  */
    5138                 :            :                 else
    5139                 :          0 :                   gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1,
    5140                 :          0 :                                                   build_int_cst (type, 1));
    5141                 :            :                 changed = true;
    5142                 :            :                 break;
    5143                 :            :               }
    5144                 :            :           }
    5145                 :            : 
    5146                 :  166369000 :         unsigned old_num_ops = gimple_num_ops (stmt);
    5147                 :  166369000 :         tree lhs = gimple_assign_lhs (stmt);
    5148                 :  166369000 :         tree new_rhs = fold_gimple_assign (gsi);
    5149                 :  166369000 :         if (new_rhs
    5150                 :  166450000 :             && !useless_type_conversion_p (TREE_TYPE (lhs),
    5151                 :      80503 :                                            TREE_TYPE (new_rhs)))
    5152                 :          0 :           new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
    5153                 :  166369000 :         if (new_rhs
    5154                 :  166369000 :             && (!inplace
    5155                 :        395 :                 || get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
    5156                 :            :           {
    5157                 :      80503 :             gimple_assign_set_rhs_from_tree (gsi, new_rhs);
    5158                 :      80503 :             changed = true;
    5159                 :            :           }
    5160                 :            :         break;
    5161                 :            :       }
    5162                 :            : 
    5163                 :   35828800 :     case GIMPLE_CALL:
    5164                 :   35828800 :       changed |= gimple_fold_call (gsi, inplace);
    5165                 :   35828800 :       break;
    5166                 :            : 
    5167                 :     522199 :     case GIMPLE_ASM:
    5168                 :            :       /* Fold *& in asm operands.  */
    5169                 :     522199 :       {
    5170                 :     522199 :         gasm *asm_stmt = as_a <gasm *> (stmt);
    5171                 :     522199 :         size_t noutputs;
    5172                 :     522199 :         const char **oconstraints;
    5173                 :     522199 :         const char *constraint;
    5174                 :     522199 :         bool allows_mem, allows_reg;
    5175                 :            : 
    5176                 :     522199 :         noutputs = gimple_asm_noutputs (asm_stmt);
    5177                 :     522199 :         oconstraints = XALLOCAVEC (const char *, noutputs);
    5178                 :            : 
    5179                 :    1197390 :         for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
    5180                 :            :           {
    5181                 :     675191 :             tree link = gimple_asm_output_op (asm_stmt, i);
    5182                 :     675191 :             tree op = TREE_VALUE (link);
    5183                 :     675191 :             oconstraints[i]
    5184                 :     675191 :               = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    5185                 :     675191 :             if (REFERENCE_CLASS_P (op)
    5186                 :     675191 :                 && (op = maybe_fold_reference (op, true)) != NULL_TREE)
    5187                 :            :               {
    5188                 :          0 :                 TREE_VALUE (link) = op;
    5189                 :          0 :                 changed = true;
    5190                 :            :               }
    5191                 :            :           }
    5192                 :     873459 :         for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
    5193                 :            :           {
    5194                 :     351260 :             tree link = gimple_asm_input_op (asm_stmt, i);
    5195                 :     351260 :             tree op = TREE_VALUE (link);
    5196                 :     351260 :             constraint
    5197                 :     351260 :               = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    5198                 :     351260 :             parse_input_constraint (&constraint, 0, 0, noutputs, 0,
    5199                 :            :                                     oconstraints, &allows_mem, &allows_reg);
    5200                 :     351260 :             if (REFERENCE_CLASS_P (op)
    5201                 :     351260 :                 && (op = maybe_fold_reference (op, !allows_reg && allows_mem))
    5202                 :            :                    != NULL_TREE)
    5203                 :            :               {
    5204                 :          0 :                 TREE_VALUE (link) = op;
    5205                 :          0 :                 changed = true;
    5206                 :            :               }
    5207                 :            :           }
    5208                 :            :       }
    5209                 :     522199 :       break;
    5210                 :            : 
    5211                 :  236132000 :     case GIMPLE_DEBUG:
    5212                 :  236132000 :       if (gimple_debug_bind_p (stmt))
    5213                 :            :         {
    5214                 :  175453000 :           tree val = gimple_debug_bind_get_value (stmt);
    5215                 :  175453000 :           if (val
    5216                 :   96797600 :               && REFERENCE_CLASS_P (val))
    5217                 :            :             {
    5218                 :     932045 :               tree tem = maybe_fold_reference (val, false);
    5219                 :     932045 :               if (tem)
    5220                 :            :                 {
    5221                 :        178 :                   gimple_debug_bind_set_value (stmt, tem);
    5222                 :        178 :                   changed = true;
    5223                 :            :                 }
    5224                 :            :             }
    5225                 :  174521000 :           else if (val
    5226                 :   95865600 :                    && TREE_CODE (val) == ADDR_EXPR)
    5227                 :            :             {
    5228                 :   24685200 :               tree ref = TREE_OPERAND (val, 0);
    5229                 :   24685200 :               tree tem = maybe_fold_reference (ref, false);
    5230                 :   24685200 :               if (tem)
    5231                 :            :                 {
    5232                 :       9557 :                   tem = build_fold_addr_expr_with_type (tem, TREE_TYPE (val));
    5233                 :       9557 :                   gimple_debug_bind_set_value (stmt, tem);
    5234                 :       9557 :                   changed = true;
    5235                 :            :                 }
    5236                 :            :             }
    5237                 :            :         }
    5238                 :            :       break;
    5239                 :            : 
    5240                 :    6950900 :     case GIMPLE_RETURN:
    5241                 :    6950900 :       {
    5242                 :    6950900 :         greturn *ret_stmt = as_a<greturn *> (stmt);
    5243                 :    6950900 :         tree ret = gimple_return_retval(ret_stmt);
    5244                 :            : 
    5245                 :    6950900 :         if (ret && TREE_CODE (ret) == SSA_NAME && valueize)
    5246                 :            :           {
    5247                 :    2774200 :             tree val = valueize (ret);
    5248                 :    2774200 :             if (val && val != ret
    5249                 :    2774200 :                 && may_propagate_copy (ret, val))
    5250                 :            :               {
    5251                 :          0 :                 gimple_return_set_retval (ret_stmt, val);
    5252                 :          0 :                 changed = true;
    5253                 :            :               }
    5254                 :            :           }
    5255                 :            :       }
    5256                 :            :       break;
    5257                 :            : 
    5258                 :  478004000 :     default:;
    5259                 :            :     }
    5260                 :            : 
    5261                 :  478004000 :   stmt = gsi_stmt (*gsi);
    5262                 :            : 
    5263                 :            :   /* Fold *& on the lhs.  */
    5264                 :  513755000 :   if (gimple_has_lhs (stmt))
    5265                 :            :     {
    5266                 :  181024000 :       tree lhs = gimple_get_lhs (stmt);
    5267                 :  181024000 :       if (lhs && REFERENCE_CLASS_P (lhs))
    5268                 :            :         {
    5269                 :   43813800 :           tree new_lhs = maybe_fold_reference (lhs, true);
    5270                 :   43813800 :           if (new_lhs)
    5271                 :            :             {
    5272                 :          0 :               gimple_set_lhs (stmt, new_lhs);
    5273                 :          0 :               changed = true;
    5274                 :            :             }
    5275                 :            :         }
    5276                 :            :     }
    5277                 :            : 
    5278                 :  478004000 :   fold_undefer_overflow_warnings (changed && !nowarning, stmt, 0);
    5279                 :  478004000 :   return changed;
    5280                 :            : }
    5281                 :            : 
    5282                 :            : /* Valueziation callback that ends up not following SSA edges.  */
    5283                 :            : 
    5284                 :            : tree
    5285                 : 1609790000 : no_follow_ssa_edges (tree)
    5286                 :            : {
    5287                 : 1609790000 :   return NULL_TREE;
    5288                 :            : }
    5289                 :            : 
    5290                 :            : /* Valueization callback that ends up following single-use SSA edges only.  */
    5291                 :            : 
    5292                 :            : tree
    5293                 :  304359000 : follow_single_use_edges (tree val)
    5294                 :            : {
    5295                 :  304359000 :   if (TREE_CODE (val) == SSA_NAME
    5296                 :  304359000 :       && !has_single_use (val))
    5297                 :  154956000 :     return NULL_TREE;
    5298                 :            :   return val;
    5299                 :            : }
    5300                 :            : 
    5301                 :            : /* Valueization callback that follows all SSA edges.  */
    5302                 :            : 
    5303                 :            : tree
    5304                 :    7853680 : follow_all_ssa_edges (tree val)
    5305                 :            : {
    5306                 :    7853680 :   return val;
    5307                 :            : }
    5308                 :            : 
    5309                 :            : /* Fold the statement pointed to by GSI.  In some cases, this function may
    5310                 :            :    replace the whole statement with a new one.  Returns true iff folding
    5311                 :            :    makes any changes.
    5312                 :            :    The statement pointed to by GSI should be in valid gimple form but may
    5313                 :            :    be in unfolded state as resulting from for example constant propagation
    5314                 :            :    which can produce *&x = 0.  */
    5315                 :            : 
    5316                 :            : bool
    5317                 :   93738600 : fold_stmt (gimple_stmt_iterator *gsi)
    5318                 :            : {
    5319                 :   93738600 :   return fold_stmt_1 (gsi, false, no_follow_ssa_edges);
    5320                 :            : }
    5321                 :            : 
    5322                 :            : bool
    5323                 :  382409000 : fold_stmt (gimple_stmt_iterator *gsi, tree (*valueize) (tree))
    5324                 :            : {
    5325                 :  382409000 :   return fold_stmt_1 (gsi, false, valueize);
    5326                 :            : }
    5327                 :            : 
    5328                 :            : /* Perform the minimal folding on statement *GSI.  Only operations like
    5329                 :            :    *&x created by constant propagation are handled.  The statement cannot
    5330                 :            :    be replaced with a new one.  Return true if the statement was
    5331                 :            :    changed, false otherwise.
    5332                 :            :    The statement *GSI should be in valid gimple form but may
    5333                 :            :    be in unfolded state as resulting from for example constant propagation
    5334                 :            :    which can produce *&x = 0.  */
    5335                 :            : 
    5336                 :            : bool
    5337                 :    1856280 : fold_stmt_inplace (gimple_stmt_iterator *gsi)
    5338                 :            : {
    5339                 :    1856280 :   gimple *stmt = gsi_stmt (*gsi);
    5340                 :    1856280 :   bool changed = fold_stmt_1 (gsi, true, no_follow_ssa_edges);
    5341                 :    1856280 :   gcc_assert (gsi_stmt (*gsi) == stmt);
    5342                 :    1856280 :   return changed;
    5343                 :            : }
    5344                 :            : 
    5345                 :            : /* Canonicalize and possibly invert the boolean EXPR; return NULL_TREE 
    5346                 :            :    if EXPR is null or we don't know how.
    5347                 :            :    If non-null, the result always has boolean type.  */
    5348                 :            : 
    5349                 :            : static tree
    5350                 :     112523 : canonicalize_bool (tree expr, bool invert)
    5351                 :            : {
    5352                 :     112523 :   if (!expr)
    5353                 :            :     return NULL_TREE;
    5354                 :        255 :   else if (invert)
    5355                 :            :     {
    5356                 :        138 :       if (integer_nonzerop (expr))
    5357                 :          0 :         return boolean_false_node;
    5358                 :        138 :       else if (integer_zerop (expr))
    5359                 :          0 :         return boolean_true_node;
    5360                 :        138 :       else if (TREE_CODE (expr) == SSA_NAME)
    5361                 :          0 :         return fold_build2 (EQ_EXPR, boolean_type_node, expr,
    5362                 :            :                             build_int_cst (TREE_TYPE (expr), 0));
    5363                 :        138 :       else if (COMPARISON_CLASS_P (expr))
    5364                 :        138 :         return fold_build2 (invert_tree_comparison (TREE_CODE (expr), false),
    5365                 :            :                             boolean_type_node,
    5366                 :            :                             TREE_OPERAND (expr, 0),
    5367                 :            :                             TREE_OPERAND (expr, 1));
    5368                 :            :       else
    5369                 :            :         return NULL_TREE;
    5370                 :            :     }
    5371                 :            :   else
    5372                 :            :     {
    5373                 :        117 :       if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
    5374                 :            :         return expr;
    5375                 :          0 :       if (integer_nonzerop (expr))
    5376                 :          0 :         return boolean_true_node;
    5377                 :          0 :       else if (integer_zerop (expr))
    5378                 :          0 :         return boolean_false_node;
    5379                 :          0 :       else if (TREE_CODE (expr) == SSA_NAME)
    5380                 :          0 :         return fold_build2 (NE_EXPR, boolean_type_node, expr,
    5381                 :            :                             build_int_cst (TREE_TYPE (expr), 0));
    5382                 :          0 :       else if (COMPARISON_CLASS_P (expr))
    5383                 :          0 :         return fold_build2 (TREE_CODE (expr),
    5384                 :            :                             boolean_type_node,
    5385                 :            :                             TREE_OPERAND (expr, 0),
    5386                 :            :                             TREE_OPERAND (expr, 1));
    5387                 :            :       else
    5388                 :            :         return NULL_TREE;
    5389                 :            :     }
    5390                 :            : }
    5391                 :            : 
    5392                 :            : /* Check to see if a boolean expression EXPR is logically equivalent to the
    5393                 :            :    comparison (OP1 CODE OP2).  Check for various identities involving
    5394                 :            :    SSA_NAMEs.  */
    5395                 :            : 
    5396                 :            : static bool
    5397                 :        796 : same_bool_comparison_p (const_tree expr, enum tree_code code,
    5398                 :            :                         const_tree op1, const_tree op2)
    5399                 :            : {
    5400                 :        802 :   gimple *s;
    5401                 :            : 
    5402                 :            :   /* The obvious case.  */
    5403                 :        802 :   if (TREE_CODE (expr) == code
    5404                 :        194 :       && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
    5405                 :        996 :       && operand_equal_p (TREE_OPERAND (expr, 1), op2, 0))
    5406                 :            :     return true;
    5407                 :            : 
    5408                 :            :   /* Check for comparing (name, name != 0) and the case where expr
    5409                 :            :      is an SSA_NAME with a definition matching the comparison.  */
    5410                 :        698 :   if (TREE_CODE (expr) == SSA_NAME
    5411                 :        702 :       && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
    5412                 :            :     {
    5413                 :          4 :       if (operand_equal_p (expr, op1, 0))
    5414                 :          4 :         return ((code == NE_EXPR && integer_zerop (op2))
    5415                 :          4 :                 || (code == EQ_EXPR && integer_nonzerop (op2)));
    5416                 :          0 :       s = SSA_NAME_DEF_STMT (expr);
    5417                 :          0 :       if (is_gimple_assign (s)
    5418                 :          0 :           && gimple_assign_rhs_code (s) == code
    5419                 :          0 :           && operand_equal_p (gimple_assign_rhs1 (s), op1, 0)
    5420                 :          0 :           && operand_equal_p (gimple_assign_rhs2 (s), op2, 0))
    5421                 :            :         return true;
    5422                 :            :     }
    5423                 :            : 
    5424                 :            :   /* If op1 is of the form (name != 0) or (name == 0), and the definition
    5425                 :            :      of name is a comparison, recurse.  */
    5426                 :        694 :   if (TREE_CODE (op1) == SSA_NAME
    5427                 :       1388 :       && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
    5428                 :            :     {
    5429                 :        340 :       s = SSA_NAME_DEF_STMT (op1);
    5430                 :        340 :       if (is_gimple_assign (s)
    5431                 :        340 :           && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
    5432                 :            :         {
    5433                 :         25 :           enum tree_code c = gimple_assign_rhs_code (s);
    5434                 :          0 :           if ((c == NE_EXPR && integer_zerop (op2))
    5435                 :         25 :               || (c == EQ_EXPR && integer_nonzerop (op2)))
    5436                 :          0 :             return same_bool_comparison_p (expr, c,
    5437                 :          0 :                                            gimple_assign_rhs1 (s),
    5438                 :          0 :                                            gimple_assign_rhs2 (s));
    5439                 :          6 :           if ((c == EQ_EXPR && integer_zerop (op2))
    5440                 :         25 :               || (c == NE_EXPR && integer_nonzerop (op2)))
    5441                 :         12 :             return same_bool_comparison_p (expr,
    5442                 :            :                                            invert_tree_comparison (c, false),
    5443                 :          6 :                                            gimple_assign_rhs1 (s),
    5444                 :         12 :                                            gimple_assign_rhs2 (s));
    5445                 :            :         }
    5446                 :            :     }
    5447                 :            :   return false;
    5448                 :            : }
    5449                 :            : 
    5450                 :            : /* Check to see if two boolean expressions OP1 and OP2 are logically
    5451                 :            :    equivalent.  */
    5452                 :            : 
    5453                 :            : static bool
    5454                 :         70 : same_bool_result_p (const_tree op1, const_tree op2)
    5455                 :            : {
    5456                 :            :   /* Simple cases first.  */
    5457                 :         70 :   if (operand_equal_p (op1, op2, 0))
    5458                 :            :     return true;
    5459                 :            : 
    5460                 :            :   /* Check the cases where at least one of the operands is a comparison.
    5461                 :            :      These are a bit smarter than operand_equal_p in that they apply some
    5462                 :            :      identifies on SSA_NAMEs.  */
    5463                 :         45 :   if (COMPARISON_CLASS_P (op2)
    5464                 :         90 :       && same_bool_comparison_p (op1, TREE_CODE (op2),
    5465                 :         45 :                                  TREE_OPERAND (op2, 0),
    5466                 :         45 :                                  TREE_OPERAND (op2, 1)))
    5467                 :            :     return true;
    5468                 :         45 :   if (COMPARISON_CLASS_P (op1)
    5469                 :         90 :       && same_bool_comparison_p (op2, TREE_CODE (op1),
    5470                 :         45 :                                  TREE_OPERAND (op1, 0),
    5471                 :         45 :                                  TREE_OPERAND (op1, 1)))
    5472                 :          0 :     return true;
    5473                 :            : 
    5474                 :            :   /* Default case.  */
    5475                 :            :   return false;
    5476                 :            : }
    5477                 :            : 
    5478                 :            : /* Forward declarations for some mutually recursive functions.  */
    5479                 :            : 
    5480                 :            : static tree
    5481                 :            : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
    5482                 :            :                    enum tree_code code2, tree op2a, tree op2b);
    5483                 :            : static tree
    5484                 :            : and_var_with_comparison (tree type, tree var, bool invert,
    5485                 :            :                          enum tree_code code2, tree op2a, tree op2b);
    5486                 :            : static tree
    5487                 :            : and_var_with_comparison_1 (tree type, gimple *stmt,
    5488                 :            :                            enum tree_code code2, tree op2a, tree op2b);
    5489                 :            : static tree
    5490                 :            : or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
    5491                 :            :                   enum tree_code code2, tree op2a, tree op2b);
    5492                 :            : static tree
    5493                 :            : or_var_with_comparison (tree, tree var, bool invert,
    5494                 :            :                         enum tree_code code2, tree op2a, tree op2b);
    5495                 :            : static tree
    5496                 :            : or_var_with_comparison_1 (tree, gimple *stmt,
    5497                 :            :                           enum tree_code code2, tree op2a, tree op2b);
    5498                 :            : 
    5499                 :            : /* Helper function for and_comparisons_1:  try to simplify the AND of the
    5500                 :            :    ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
    5501                 :            :    If INVERT is true, invert the value of the VAR before doing the AND.
    5502                 :            :    Return NULL_EXPR if we can't simplify this to a single expression.  */
    5503                 :            : 
    5504                 :            : static tree
    5505                 :      90586 : and_var_with_comparison (tree type, tree var, bool invert,
    5506                 :            :                          enum tree_code code2, tree op2a, tree op2b)
    5507                 :            : {
    5508                 :      90586 :   tree t;
    5509                 :      90586 :   gimple *stmt = SSA_NAME_DEF_STMT (var);
    5510                 :            : 
    5511                 :            :   /* We can only deal with variables whose definitions are assignments.  */
    5512                 :      90586 :   if (!is_gimple_assign (stmt))
    5513                 :            :     return NULL_TREE;
    5514                 :            :   
    5515                 :            :   /* If we have an inverted comparison, apply DeMorgan's law and rewrite
    5516                 :            :      !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
    5517                 :            :      Then we only have to consider the simpler non-inverted cases.  */
    5518                 :      90252 :   if (invert)
    5519                 :      34637 :     t = or_var_with_comparison_1 (type, stmt,
    5520                 :            :                                   invert_tree_comparison (code2, false),
    5521                 :            :                                   op2a, op2b);
    5522                 :            :   else
    5523                 :      55615 :     t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
    5524                 :      90252 :   return canonicalize_bool (t, invert);
    5525                 :            : }
    5526                 :            : 
    5527                 :            : /* Try to simplify the AND of the ssa variable defined by the assignment
    5528                 :            :    STMT with the comparison specified by (OP2A CODE2 OP2B).
    5529                 :            :    Return NULL_EXPR if we can't simplify this to a single expression.  */
    5530                 :            : 
    5531                 :            : static tree
    5532                 :      63519 : and_var_with_comparison_1 (tree type, gimple *stmt,
    5533                 :            :                            enum tree_code code2, tree op2a, tree op2b)
    5534                 :            : {
    5535                 :      63519 :   tree var = gimple_assign_lhs (stmt);
    5536                 :      63519 :   tree true_test_var = NULL_TREE;
    5537                 :      63519 :   tree false_test_var = NULL_TREE;
    5538                 :      63519 :   enum tree_code innercode = gimple_assign_rhs_code (stmt);
    5539                 :            : 
    5540                 :            :   /* Check for identities like (var AND (var == 0)) => false.  */
    5541                 :      63519 :   if (TREE_CODE (op2a) == SSA_NAME
    5542                 :     126906 :       && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
    5543                 :            :     {
    5544                 :      10010 :       if ((code2 == NE_EXPR && integer_zerop (op2b))
    5545                 :      20090 :           || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
    5546                 :            :         {
    5547                 :       8899 :           true_test_var = op2a;
    5548                 :       8899 :           if (var == true_test_var)
    5549                 :            :             return var;
    5550                 :            :         }
    5551                 :       1000 :       else if ((code2 == EQ_EXPR && integer_zerop (op2b))
    5552                 :       9740 :                || (code2 == NE_EXPR && integer_nonzerop (op2b)))
    5553                 :            :         {
    5554                 :       2076 :           false_test_var = op2a;
    5555                 :       2076 :           if (var == false_test_var)
    5556                 :          0 :             return boolean_false_node;
    5557                 :            :         }
    5558                 :            :     }
    5559                 :            : 
    5560                 :            :   /* If the definition is a comparison, recurse on it.  */
    5561                 :      63519 :   if (TREE_CODE_CLASS (innercode) == tcc_comparison)
    5562                 :            :     {
    5563                 :       8827 :       tree t = and_comparisons_1 (type, innercode,
    5564                 :            :                                   gimple_assign_rhs1 (stmt),
    5565                 :            :                                   gimple_assign_rhs2 (stmt),
    5566                 :            :                                   code2,
    5567                 :            :                                   op2a,
    5568                 :            :                                   op2b);
    5569                 :       8827 :       if (t)
    5570                 :            :         return t;
    5571                 :            :     }
    5572                 :            : 
    5573                 :            :   /* If the definition is an AND or OR expression, we may be able to
    5574                 :            :      simplify by reassociating.  */
    5575                 :      63449 :   if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
    5576                 :      63449 :       && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
    5577                 :            :     {
    5578                 :       7082 :       tree inner1 = gimple_assign_rhs1 (stmt);
    5579                 :       7082 :       tree inner2 = gimple_assign_rhs2 (stmt);
    5580                 :       7082 :       gimple *s;
    5581                 :       7082 :       tree t;
    5582                 :       7082 :       tree partial = NULL_TREE;
    5583                 :       7082 :       bool is_and = (innercode == BIT_AND_EXPR);
    5584                 :            :       
    5585                 :            :       /* Check for boolean identities that don't require recursive examination
    5586                 :            :          of inner1/inner2:
    5587                 :            :          inner1 AND (inner1 AND inner2) => inner1 AND inner2 => var
    5588                 :            :          inner1 AND (inner1 OR inner2) => inner1
    5589                 :            :          !inner1 AND (inner1 AND inner2) => false
    5590                 :            :          !inner1 AND (inner1 OR inner2) => !inner1 AND inner2
    5591                 :            :          Likewise for similar cases involving inner2.  */
    5592                 :       7082 :       if (inner1 == true_test_var)
    5593                 :          0 :         return (is_and ? var : inner1);
    5594                 :       7082 :       else if (inner2 == true_test_var)
    5595                 :          0 :         return (is_and ? var : inner2);
    5596                 :       7082 :       else if (inner1 == false_test_var)
    5597                 :          0 :         return (is_and
    5598                 :          0 :                 ? boolean_false_node
    5599                 :          0 :                 : and_var_with_comparison (type, inner2, false, code2, op2a,
    5600                 :            :                                            op2b));
    5601                 :       7082 :       else if (inner2 == false_test_var)
    5602                 :          0 :         return (is_and
    5603                 :          0 :                 ? boolean_false_node
    5604                 :          0 :                 : and_var_with_comparison (type, inner1, false, code2, op2a,
    5605                 :            :                                            op2b));
    5606                 :            : 
    5607                 :            :       /* Next, redistribute/reassociate the AND across the inner tests.
    5608                 :            :          Compute the first partial result, (inner1 AND (op2a code op2b))  */
    5609                 :       7082 :       if (TREE_CODE (inner1) == SSA_NAME
    5610                 :       7082 :           && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
    5611                 :       6927 :           && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
    5612                 :      13847 :           && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
    5613                 :            :                                               gimple_assign_rhs1 (s),
    5614                 :            :                                               gimple_assign_rhs2 (s),
    5615                 :            :                                               code2, op2a, op2b)))
    5616                 :            :         {
    5617                 :            :           /* Handle the AND case, where we are reassociating:
    5618                 :            :              (inner1 AND inner2) AND (op2a code2 op2b)
    5619                 :            :              => (t AND inner2)
    5620                 :            :              If the partial result t is a constant, we win.  Otherwise
    5621                 :            :              continue on to try reassociating with the other inner test.  */
    5622                 :         21 :           if (is_and)
    5623                 :            :             {
    5624                 :          2 :               if (integer_onep (t))
    5625                 :            :                 return inner2;
    5626                 :          2 :               else if (integer_zerop (t))
    5627                 :          1 :                 return boolean_false_node;
    5628                 :            :             }
    5629                 :            : 
    5630                 :            :           /* Handle the OR case, where we are redistributing:
    5631                 :            :              (inner1 OR inner2) AND (op2a code2 op2b)
    5632                 :            :              => (t OR (inner2 AND (op2a code2 op2b)))  */
    5633                 :         19 :           else if (integer_onep (t))
    5634                 :          0 :             return boolean_true_node;
    5635                 :            : 
    5636                 :            :           /* Save partial result for later.  */
    5637                 :            :           partial = t;
    5638                 :            :         }
    5639                 :            :       
    5640                 :            :       /* Compute the second partial result, (inner2 AND (op2a code op2b)) */
    5641                 :       7081 :       if (TREE_CODE (inner2) == SSA_NAME
    5642                 :       7081 :           && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
    5643                 :       6936 :           && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
    5644                 :      13757 :           && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
    5645                 :            :                                               gimple_assign_rhs1 (s),
    5646                 :            :                                               gimple_assign_rhs2 (s),
    5647                 :            :                                               code2, op2a, op2b)))
    5648                 :            :         {
    5649                 :            :           /* Handle the AND case, where we are reassociating:
    5650                 :            :              (inner1 AND inner2) AND (op2a code2 op2b)
    5651                 :            :              => (inner1 AND t)  */
    5652                 :         31 :           if (is_and)
    5653                 :            :             {
    5654                 :          2 :               if (integer_onep (t))
    5655                 :            :                 return inner1;
    5656                 :          2 :               else if (integer_zerop (t))
    5657                 :          1 :                 return boolean_false_node;
    5658                 :            :               /* If both are the same, we can apply the identity
    5659                 :            :                  (x AND x) == x.  */
    5660                 :          1 :               else if (partial && same_bool_result_p (t, partial))
    5661                 :          0 :                 return t;
    5662                 :            :             }
    5663                 :            : 
    5664                 :            :           /* Handle the OR case. where we are redistributing:
    5665                 :            :              (inner1 OR inner2) AND (op2a code2 op2b)
    5666                 :            :              => (t OR (inner1 AND (op2a code2 op2b)))
    5667                 :            :              => (t OR partial)  */
    5668                 :            :           else
    5669                 :            :             {
    5670                 :         29 :               if (integer_onep (t))
    5671                 :          0 :                 return boolean_true_node;
    5672                 :         29 :               else if (partial)
    5673                 :            :                 {
    5674                 :            :                   /* We already got a simplification for the other
    5675                 :            :                      operand to the redistributed OR expression.  The
    5676                 :            :                      interesting case is when at least one is false.
    5677                 :            :                      Or, if both are the same, we can apply the identity
    5678                 :            :                      (x OR x) == x.  */
    5679                 :         14 :                   if (integer_zerop (partial))
    5680                 :            :                     return t;
    5681                 :         14 :                   else if (integer_zerop (t))
    5682                 :            :                     return partial;
    5683                 :         12 :                   else if (same_bool_result_p (t, partial))
    5684                 :          0 :                     return t;
    5685                 :            :                 }
    5686                 :            :             }
    5687                 :            :         }
    5688                 :            :     }
    5689                 :            :   return NULL_TREE;
    5690                 :            : }
    5691                 :            : 
    5692                 :            : /* Try to simplify the AND of two comparisons defined by
    5693                 :            :    (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
    5694                 :            :    If this can be done without constructing an intermediate value,
    5695                 :            :    return the resulting tree; otherwise NULL_TREE is returned.
    5696                 :            :    This function is deliberately asymmetric as it recurses on SSA_DEFs
    5697                 :            :    in the first comparison but not the second.  */
    5698                 :            : 
    5699                 :            : static tree
    5700                 :     361590 : and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
    5701                 :            :                    enum tree_code code2, tree op2a, tree op2b)
    5702                 :            : {
    5703                 :     361590 :   tree truth_type = truth_type_for (TREE_TYPE (op1a));
    5704                 :            : 
    5705                 :            :   /* First check for ((x CODE1 y) AND (x CODE2 y)).  */
    5706                 :     361590 :   if (operand_equal_p (op1a, op2a, 0)
    5707                 :     361590 :       && operand_equal_p (op1b, op2b, 0))
    5708                 :            :     {
    5709                 :            :       /* Result will be either NULL_TREE, or a combined comparison.  */
    5710                 :        802 :       tree t = combine_comparisons (UNKNOWN_LOCATION,
    5711                 :            :                                     TRUTH_ANDIF_EXPR, code1, code2,
    5712                 :            :                                     truth_type, op1a, op1b);
    5713                 :        802 :       if (t)
    5714                 :            :         return t;
    5715                 :            :     }
    5716                 :            : 
    5717                 :            :   /* Likewise the swapped case of the above.  */
    5718                 :     361152 :   if (operand_equal_p (op1a, op2b, 0)
    5719                 :     361152 :       && operand_equal_p (op1b, op2a, 0))
    5720                 :            :     {
    5721                 :            :       /* Result will be either NULL_TREE, or a combined comparison.  */
    5722                 :         25 :       tree t = combine_comparisons (UNKNOWN_LOCATION,
    5723                 :            :                                     TRUTH_ANDIF_EXPR, code1,
    5724                 :            :                                     swap_tree_comparison (code2),
    5725                 :            :                                     truth_type, op1a, op1b);
    5726                 :         25 :       if (t)
    5727                 :            :         return t;
    5728                 :            :     }
    5729                 :            : 
    5730                 :            :   /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
    5731                 :            :      NAME's definition is a truth value.  See if there are any simplifications
    5732                 :            :      that can be done against the NAME's definition.  */
    5733                 :     361127 :   if (TREE_CODE (op1a) == SSA_NAME
    5734                 :     360398 :       && (code1 == NE_EXPR || code1 == EQ_EXPR)
    5735                 :     551238 :       && (integer_zerop (op1b) || integer_onep (op1b)))
    5736                 :            :     {
    5737                 :      45036 :       bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
    5738                 :     129366 :                      || (code1 == NE_EXPR && integer_onep (op1b)));
    5739                 :     124001 :       gimple *stmt = SSA_NAME_DEF_STMT (op1a);
    5740                 :     124001 :       switch (gimple_code (stmt))
    5741                 :            :         {
    5742                 :      89586 :         case GIMPLE_ASSIGN:
    5743                 :            :           /* Try to simplify by copy-propagating the definition.  */
    5744                 :      89586 :           return and_var_with_comparison (type, op1a, invert, code2, op2a,
    5745                 :      89586 :                                           op2b);
    5746                 :            : 
    5747                 :      11581 :         case GIMPLE_PHI:
    5748                 :            :           /* If every argument to the PHI produces the same result when
    5749                 :            :              ANDed with the second comparison, we win.
    5750                 :            :              Do not do this unless the type is bool since we need a bool
    5751                 :            :              result here anyway.  */
    5752                 :      11581 :           if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
    5753                 :            :             {
    5754                 :            :               tree result = NULL_TREE;
    5755                 :            :               unsigned i;
    5756                 :       3834 :               for (i = 0; i < gimple_phi_num_args (stmt); i++)
    5757                 :            :                 {
    5758                 :       3834 :                   tree arg = gimple_phi_arg_def (stmt, i);
    5759                 :            :                   
    5760                 :            :                   /* If this PHI has itself as an argument, ignore it.
    5761                 :            :                      If all the other args produce the same result,
    5762                 :            :                      we're still OK.  */
    5763                 :       3834 :                   if (arg == gimple_phi_result (stmt))
    5764                 :          0 :                     continue;
    5765                 :       3834 :                   else if (TREE_CODE (arg) == INTEGER_CST)
    5766                 :            :                     {
    5767                 :       2471 :                       if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
    5768                 :            :                         {
    5769                 :       1242 :                           if (!result)
    5770                 :        662 :                             result = boolean_false_node;
    5771                 :        580 :                           else if (!integer_zerop (result))
    5772                 :            :                             return NULL_TREE;
    5773                 :            :                         }
    5774                 :       1229 :                       else if (!result)
    5775                 :        675 :                         result = fold_build2 (code2, boolean_type_node,
    5776                 :            :                                               op2a, op2b);
    5777                 :        554 :                       else if (!same_bool_comparison_p (result,
    5778                 :            :                                                         code2, op2a, op2b))
    5779                 :            :                         return NULL_TREE;
    5780                 :            :                     }
    5781                 :       1363 :                   else if (TREE_CODE (arg) == SSA_NAME
    5782                 :       1363 :                            && !SSA_NAME_IS_DEFAULT_DEF (arg))
    5783                 :            :                     {
    5784                 :       1357 :                       tree temp;
    5785                 :       1357 :                       gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
    5786                 :            :                       /* In simple cases we can look through PHI nodes,
    5787                 :            :                          but we have to be careful with loops.
    5788                 :            :                          See PR49073.  */
    5789                 :       1357 :                       if (! dom_info_available_p (CDI_DOMINATORS)
    5790                 :       1357 :                           || gimple_bb (def_stmt) == gimple_bb (stmt)
    5791                 :       2714 :                           || dominated_by_p (CDI_DOMINATORS,
    5792                 :       1357 :                                              gimple_bb (def_stmt),
    5793                 :       1357 :                                              gimple_bb (stmt)))
    5794                 :        357 :                         return NULL_TREE;
    5795                 :       1000 :                       temp = and_var_with_comparison (type, arg, invert, code2,
    5796                 :            :                                                       op2a, op2b);
    5797                 :       1000 :                       if (!temp)
    5798                 :            :                         return NULL_TREE;
    5799                 :          0 :                       else if (!result)
    5800                 :            :                         result = temp;
    5801                 :          0 :                       else if (!same_bool_result_p (result, temp))
    5802                 :            :                         return NULL_TREE;
    5803                 :            :                     }
    5804                 :            :                   else
    5805                 :            :                     return NULL_TREE;
    5806                 :            :                 }
    5807                 :          0 :               return result;
    5808                 :            :             }
    5809                 :            : 
    5810                 :            :         default:
    5811                 :            :           break;
    5812                 :            :         }
    5813                 :            :     }
    5814                 :            :   return NULL_TREE;
    5815                 :            : }
    5816                 :            : 
    5817                 :            : /* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
    5818                 :            :    : try to simplify the AND/OR of the ssa variable VAR with the comparison
    5819                 :            :    specified by (OP2A CODE2 OP2B) from match.pd.  Return NULL_EXPR if we can't
    5820                 :            :    simplify this to a single expression.  As we are going to lower the cost
    5821                 :            :    of building SSA names / gimple stmts significantly, we need to allocate
    5822                 :            :    them ont the stack.  This will cause the code to be a bit ugly.  */
    5823                 :            : 
    5824                 :            : static tree
    5825                 :     327594 : maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
    5826                 :            :                                       enum tree_code code1,
    5827                 :            :                                       tree op1a, tree op1b,
    5828                 :            :                                       enum tree_code code2, tree op2a,
    5829                 :            :                                       tree op2b)
    5830                 :            : {
    5831                 :            :   /* Allocate gimple stmt1 on the stack.  */
    5832                 :     327594 :   gassign *stmt1
    5833                 :     327594 :     = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
    5834                 :     327594 :   gimple_init (stmt1, GIMPLE_ASSIGN, 3);
    5835                 :     327594 :   gimple_assign_set_rhs_code (stmt1, code1);
    5836                 :     327594 :   gimple_assign_set_rhs1 (stmt1, op1a);
    5837                 :     327594 :   gimple_assign_set_rhs2 (stmt1, op1b);
    5838                 :            : 
    5839                 :            :   /* Allocate gimple stmt2 on the stack.  */
    5840                 :     327594 :   gassign *stmt2
    5841                 :     327594 :     = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
    5842                 :     327594 :   gimple_init (stmt2, GIMPLE_ASSIGN, 3);
    5843                 :     327594 :   gimple_assign_set_rhs_code (stmt2, code2);
    5844                 :     327594 :   gimple_assign_set_rhs1 (stmt2, op2a);
    5845                 :     327594 :   gimple_assign_set_rhs2 (stmt2, op2b);
    5846                 :            : 
    5847                 :            :   /* Allocate SSA names(lhs1) on the stack.  */
    5848                 :     327594 :   tree lhs1 = (tree)XALLOCA (tree_ssa_name);
    5849                 :     327594 :   memset (lhs1, 0, sizeof (tree_ssa_name));
    5850                 :     327594 :   TREE_SET_CODE (lhs1, SSA_NAME);
    5851                 :     327594 :   TREE_TYPE (lhs1) = type;
    5852                 :     327594 :   init_ssa_name_imm_use (lhs1);
    5853                 :            : 
    5854                 :            :   /* Allocate SSA names(lhs2) on the stack.  */
    5855                 :     327594 :   tree lhs2 = (tree)XALLOCA (tree_ssa_name);
    5856                 :     327594 :   memset (lhs2, 0, sizeof (tree_ssa_name));
    5857                 :     327594 :   TREE_SET_CODE (lhs2, SSA_NAME);
    5858                 :     327594 :   TREE_TYPE (lhs2) = type;
    5859                 :     327594 :   init_ssa_name_imm_use (lhs2);
    5860                 :            : 
    5861                 :     327594 :   gimple_assign_set_lhs (stmt1, lhs1);
    5862                 :     327594 :   gimple_assign_set_lhs (stmt2, lhs2);
    5863                 :            : 
    5864                 :     327594 :   gimple_match_op op (gimple_match_cond::UNCOND, code,
    5865                 :            :                       type, gimple_assign_lhs (stmt1),
    5866                 :     327594 :                       gimple_assign_lhs (stmt2));
    5867                 :     327594 :   if (op.resimplify (NULL, follow_all_ssa_edges))
    5868                 :            :     {
    5869                 :        378 :       if (gimple_simplified_result_is_gimple_val (&op))
    5870                 :            :         {
    5871                 :        290 :           tree res = op.ops[0];
    5872                 :        290 :           if (res == lhs1)
    5873                 :        214 :             return build2 (code1, type, op1a, op1b);
    5874                 :         76 :           else if (res == lhs2)
    5875                 :         73 :             return build2 (code2, type, op2a, op2b);
    5876                 :            :           else
    5877                 :            :             return res;
    5878                 :            :         }
    5879                 :         88 :       else if (op.code.is_tree_code ()
    5880                 :         88 :                && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
    5881                 :            :         {
    5882                 :         88 :           tree op0 = op.ops[0];
    5883                 :         88 :           tree op1 = op.ops[1];
    5884                 :         88 :           if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
    5885                 :            :             return NULL_TREE;  /* not simple */
    5886                 :            : 
    5887                 :         88 :           return build2 ((enum tree_code)op.code, op.type, op0, op1);
    5888                 :            :         }
    5889                 :            :     }
    5890                 :            : 
    5891                 :            :   return NULL_TREE;
    5892                 :            : }
    5893                 :            : 
    5894                 :            : /* Try to simplify the AND of two comparisons, specified by
    5895                 :            :    (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
    5896                 :            :    If this can be simplified to a single expression (without requiring
    5897                 :            :    introducing more SSA variables to hold intermediate values),
    5898                 :            :    return the resulting tree.  Otherwise return NULL_TREE.
    5899                 :            :    If the result expression is non-null, it has boolean type.  */
    5900                 :            : 
    5901                 :            : tree
    5902                 :     176673 : maybe_fold_and_comparisons (tree type,
    5903                 :            :                             enum tree_code code1, tree op1a, tree op1b,
    5904                 :            :                             enum tree_code code2, tree op2a, tree op2b)
    5905                 :            : {
    5906                 :     176673 :   if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b))
    5907                 :            :     return t;
    5908                 :            : 
    5909                 :     176090 :   if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b))
    5910                 :            :     return t;
    5911                 :            : 
    5912                 :     176068 :   if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1,
    5913                 :            :                                                      op1a, op1b, code2, op2a,
    5914                 :            :                                                      op2b))
    5915                 :        227 :     return t;
    5916                 :            : 
    5917                 :            :   return NULL_TREE;
    5918                 :            : }
    5919                 :            : 
    5920                 :            : /* Helper function for or_comparisons_1:  try to simplify the OR of the
    5921                 :            :    ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
    5922                 :            :    If INVERT is true, invert the value of VAR before doing the OR.
    5923                 :            :    Return NULL_EXPR if we can't simplify this to a single expression.  */
    5924                 :            : 
    5925                 :            : static tree
    5926                 :      22339 : or_var_with_comparison (tree type, tree var, bool invert,
    5927                 :            :                         enum tree_code code2, tree op2a, tree op2b)
    5928                 :            : {
    5929                 :      22339 :   tree t;
    5930                 :      22339 :   gimple *stmt = SSA_NAME_DEF_STMT (var);
    5931                 :            : 
    5932                 :            :   /* We can only deal with variables whose definitions are assignments.  */
    5933                 :      22339 :   if (!is_gimple_assign (stmt))
    5934                 :            :     return NULL_TREE;
    5935                 :            :   
    5936                 :            :   /* If we have an inverted comparison, apply DeMorgan's law and rewrite
    5937                 :            :      !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
    5938                 :            :      Then we only have to consider the simpler non-inverted cases.  */
    5939                 :      22271 :   if (invert)
    5940                 :       7904 :     t = and_var_with_comparison_1 (type, stmt,
    5941                 :            :                                    invert_tree_comparison (code2, false),
    5942                 :            :                                    op2a, op2b);
    5943                 :            :   else
    5944                 :      14367 :     t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
    5945                 :      22271 :   return canonicalize_bool (t, invert);
    5946                 :            : }
    5947                 :            : 
    5948                 :            : /* Try to simplify the OR of the ssa variable defined by the assignment
    5949                 :            :    STMT with the comparison specified by (OP2A CODE2 OP2B).
    5950                 :            :    Return NULL_EXPR if we can't simplify this to a single expression.  */
    5951                 :            : 
    5952                 :            : static tree
    5953                 :      49004 : or_var_with_comparison_1 (tree type, gimple *stmt,
    5954                 :            :                           enum tree_code code2, tree op2a, tree op2b)
    5955                 :            : {
    5956                 :      49004 :   tree var = gimple_assign_lhs (stmt);
    5957                 :      49004 :   tree true_test_var = NULL_TREE;
    5958                 :      49004 :   tree false_test_var = NULL_TREE;
    5959                 :      49004 :   enum tree_code innercode = gimple_assign_rhs_code (stmt);
    5960                 :            : 
    5961                 :            :   /* Check for identities like (var OR (var != 0)) => true .  */
    5962                 :      49004 :   if (TREE_CODE (op2a) == SSA_NAME
    5963                 :      97300 :       && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
    5964                 :            :     {
    5965                 :      13464 :       if ((code2 == NE_EXPR && integer_zerop (op2b))
    5966                 :      31929 :           || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
    5967                 :            :         {
    5968                 :      18584 :           true_test_var = op2a;
    5969                 :      18584 :           if (var == true_test_var)
    5970                 :            :             return var;
    5971                 :            :         }
    5972                 :       2008 :       else if ((code2 == EQ_EXPR && integer_zerop (op2b))
    5973                 :      10225 :                || (code2 == NE_EXPR && integer_nonzerop (op2b)))
    5974                 :            :         {
    5975                 :       4079 :           false_test_var = op2a;
    5976                 :       4079 :           if (var == false_test_var)
    5977                 :          0 :             return boolean_true_node;
    5978                 :            :         }
    5979                 :            :     }
    5980                 :            : 
    5981                 :            :   /* If the definition is a comparison, recurse on it.  */
    5982                 :      49004 :   if (TREE_CODE_CLASS (innercode) == tcc_comparison)
    5983                 :            :     {
    5984                 :       6629 :       tree t = or_comparisons_1 (type, innercode,
    5985                 :            :                                  gimple_assign_rhs1 (stmt),
    5986                 :            :                                  gimple_assign_rhs2 (stmt),
    5987                 :            :                                  code2,
    5988                 :            :                                  op2a,
    5989                 :            :                                  op2b);
    5990                 :       6629 :       if (t)
    5991                 :            :         return t;
    5992                 :            :     }
    5993                 :            :   
    5994                 :            :   /* If the definition is an AND or OR expression, we may be able to
    5995                 :            :      simplify by reassociating.  */
    5996                 :      48875 :   if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
    5997                 :      48875 :       && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
    5998                 :            :     {
    5999                 :      19891 :       tree inner1 = gimple_assign_rhs1 (stmt);
    6000                 :      19891 :       tree inner2 = gimple_assign_rhs2 (stmt);
    6001                 :      19891 :       gimple *s;
    6002                 :      19891 :       tree t;
    6003                 :      19891 :       tree partial = NULL_TREE;
    6004                 :      19891 :       bool is_or = (innercode == BIT_IOR_EXPR);
    6005                 :            :       
    6006                 :            :       /* Check for boolean identities that don't require recursive examination
    6007                 :            :          of inner1/inner2:
    6008                 :            :          inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
    6009                 :            :          inner1 OR (inner1 AND inner2) => inner1
    6010                 :            :          !inner1 OR (inner1 OR inner2) => true
    6011                 :            :          !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
    6012                 :            :       */
    6013                 :      19891 :       if (inner1 == true_test_var)
    6014                 :          0 :         return (is_or ? var : inner1);
    6015                 :      19891 :       else if (inner2 == true_test_var)
    6016                 :          0 :         return (is_or ? var : inner2);
    6017                 :      19891 :       else if (inner1 == false_test_var)
    6018                 :          0 :         return (is_or
    6019                 :          0 :                 ? boolean_true_node
    6020                 :          0 :                 : or_var_with_comparison (type, inner2, false, code2, op2a,
    6021                 :            :                                           op2b));
    6022                 :      19891 :       else if (inner2 == false_test_var)
    6023                 :          0 :         return (is_or
    6024                 :          0 :                 ? boolean_true_node
    6025                 :          0 :                 : or_var_with_comparison (type, inner1, false, code2, op2a,
    6026                 :            :                                           op2b));
    6027                 :            :       
    6028                 :            :       /* Next, redistribute/reassociate the OR across the inner tests.
    6029                 :            :          Compute the first partial result, (inner1 OR (op2a code op2b))  */
    6030                 :      19891 :       if (TREE_CODE (inner1) == SSA_NAME
    6031                 :      19891 :           && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
    6032                 :      19472 :           && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
    6033                 :      38098 :           && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
    6034                 :            :                                              gimple_assign_rhs1 (s),
    6035                 :            :                                              gimple_assign_rhs2 (s),
    6036                 :            :                                              code2, op2a, op2b)))
    6037                 :            :         {
    6038                 :            :           /* Handle the OR case, where we are reassociating:
    6039                 :            :              (inner1 OR inner2) OR (op2a code2 op2b)
    6040                 :            :              => (t OR inner2)
    6041                 :            :              If the partial result t is a constant, we win.  Otherwise
    6042                 :            :              continue on to try reassociating with the other inner test.  */
    6043                 :        194 :           if (is_or)
    6044                 :            :             {
    6045                 :         44 :               if (integer_onep (t))
    6046                 :          0 :                 return boolean_true_node;
    6047                 :         44 :               else if (integer_zerop (t))
    6048                 :            :                 return inner2;
    6049                 :            :             }
    6050                 :            :           
    6051                 :            :           /* Handle the AND case, where we are redistributing:
    6052                 :            :              (inner1 AND inner2) OR (op2a code2 op2b)
    6053                 :            :              => (t AND (inner2 OR (op2a code op2b)))  */
    6054                 :        150 :           else if (integer_zerop (t))
    6055                 :          0 :             return boolean_false_node;
    6056                 :            : 
    6057                 :            :           /* Save partial result for later.  */
    6058                 :            :           partial = t;
    6059                 :            :         }
    6060                 :            :       
    6061                 :            :       /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
    6062                 :      19891 :       if (TREE_CODE (inner2) == SSA_NAME
    6063                 :      19891 :           && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
    6064                 :      19575 :           && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
    6065                 :      38674 :           && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
    6066                 :            :                                              gimple_assign_rhs1 (s),
    6067                 :            :                                              gimple_assign_rhs2 (s),
    6068                 :            :                                              code2, op2a, op2b)))
    6069                 :            :         {
    6070                 :            :           /* Handle the OR case, where we are reassociating:
    6071                 :            :              (inner1 OR inner2) OR (op2a code2 op2b)
    6072                 :            :              => (inner1 OR t)
    6073                 :            :              => (t OR partial)  */
    6074                 :        134 :           if (is_or)
    6075                 :            :             {
    6076                 :         60 :               if (integer_zerop (t))
    6077                 :            :                 return inner1;
    6078                 :         60 :               else if (integer_onep (t))
    6079                 :          9 :                 return boolean_true_node;
    6080                 :            :               /* If both are the same, we can apply the identity
    6081                 :            :                  (x OR x) == x.  */
    6082                 :         51 :               else if (partial && same_bool_result_p (t, partial))
    6083                 :         25 :                 return t;
    6084                 :            :             }
    6085                 :            :           
    6086                 :            :           /* Handle the AND case, where we are redistributing:
    6087                 :            :              (inner1 AND inner2) OR (op2a code2 op2b)
    6088                 :            :              => (t AND (inner1 OR (op2a code2 op2b)))
    6089                 :            :              => (t AND partial)  */
    6090                 :            :           else 
    6091                 :            :             {
    6092                 :         74 :               if (integer_zerop (t))
    6093                 :          0 :                 return boolean_false_node;
    6094                 :         74 :               else if (partial)
    6095                 :            :                 {
    6096                 :            :                   /* We already got a simplification for the other
    6097                 :            :                      operand to the redistributed AND expression.  The
    6098                 :            :                      interesting case is when at least one is true.
    6099                 :            :                      Or, if both are the same, we can apply the identity
    6100                 :            :                      (x AND x) == x.  */
    6101                 :         51 :                   if (integer_onep (partial))
    6102                 :            :                     return t;
    6103                 :         51 :                   else if (integer_onep (t))
    6104                 :            :                     return partial;
    6105                 :         33 :                   else if (same_bool_result_p (t, partial))
    6106                 :          0 :                     return t;
    6107                 :            :                 }
    6108                 :            :             }
    6109                 :            :         }
    6110                 :            :     }
    6111                 :            :   return NULL_TREE;
    6112                 :            : }
    6113                 :            : 
    6114                 :            : /* Try to simplify the OR of two comparisons defined by
    6115                 :            :    (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
    6116                 :            :    If this can be done without constructing an intermediate value,
    6117                 :            :    return the resulting tree; otherwise NULL_TREE is returned.
    6118                 :            :    This function is deliberately asymmetric as it recurses on SSA_DEFs
    6119                 :            :    in the first comparison but not the second.  */
    6120                 :            : 
    6121                 :            : static tree
    6122                 :     310242 : or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
    6123                 :            :                   enum tree_code code2, tree op2a, tree op2b)
    6124                 :            : {
    6125                 :     310242 :   tree truth_type = truth_type_for (TREE_TYPE (op1a));
    6126                 :            : 
    6127                 :            :   /* First check for ((x CODE1 y) OR (x CODE2 y)).  */
    6128                 :     310242 :   if (operand_equal_p (op1a, op2a, 0)
    6129                 :     310242 :       && operand_equal_p (op1b, op2b, 0))
    6130                 :            :     {
    6131                 :            :       /* Result will be either NULL_TREE, or a combined comparison.  */
    6132                 :        584 :       tree t = combine_comparisons (UNKNOWN_LOCATION,
    6133                 :            :                                     TRUTH_ORIF_EXPR, code1, code2,
    6134                 :            :                                     truth_type, op1a, op1b);
    6135                 :        584 :       if (t)
    6136                 :            :         return t;
    6137                 :            :     }
    6138                 :            : 
    6139                 :            :   /* Likewise the swapped case of the above.  */
    6140                 :     309658 :   if (operand_equal_p (op1a, op2b, 0)
    6141                 :     309658 :       && operand_equal_p (op1b, op2a, 0))
    6142                 :            :     {
    6143                 :            :       /* Result will be either NULL_TREE, or a combined comparison.  */
    6144                 :         20 :       tree t = combine_comparisons (UNKNOWN_LOCATION,
    6145                 :            :                                     TRUTH_ORIF_EXPR, code1,
    6146                 :            :                                     swap_tree_comparison (code2),
    6147                 :            :                                     truth_type, op1a, op1b);
    6148                 :         20 :       if (t)
    6149                 :            :         return t;
    6150                 :            :     }
    6151                 :            : 
    6152                 :            :   /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
    6153                 :            :      NAME's definition is a truth value.  See if there are any simplifications
    6154                 :            :      that can be done against the NAME's definition.  */
    6155                 :     309638 :   if (TREE_CODE (op1a) == SSA_NAME
    6156                 :     308790 :       && (code1 == NE_EXPR || code1 == EQ_EXPR)
    6157                 :     517937 :       && (integer_zerop (op1b) || integer_onep (op1b)))
    6158                 :            :     {
    6159                 :      19939 :       bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
    6160                 :      42800 :                      || (code1 == NE_EXPR && integer_onep (op1b)));
    6161                 :      39463 :       gimple *stmt = SSA_NAME_DEF_STMT (op1a);
    6162                 :      39463 :       switch (gimple_code (stmt))
    6163                 :            :         {
    6164                 :      22262 :         case GIMPLE_ASSIGN:
    6165                 :            :           /* Try to simplify by copy-propagating the definition.  */
    6166                 :      22262 :           return or_var_with_comparison (type, op1a, invert, code2, op2a,
    6167                 :      22262 :                                          op2b);
    6168                 :            : 
    6169                 :       9334 :         case GIMPLE_PHI:
    6170                 :            :           /* If every argument to the PHI produces the same result when
    6171                 :            :              ORed with the second comparison, we win.
    6172                 :            :              Do not do this unless the type is bool since we need a bool
    6173                 :            :              result here anyway.  */
    6174                 :       9334 :           if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
    6175                 :            :             {
    6176                 :            :               tree result = NULL_TREE;
    6177                 :            :               unsigned i;
    6178                 :        421 :               for (i = 0; i < gimple_phi_num_args (stmt); i++)
    6179                 :            :                 {
    6180                 :        421 :                   tree arg = gimple_phi_arg_def (stmt, i);
    6181                 :            :                   
    6182                 :            :                   /* If this PHI has itself as an argument, ignore it.
    6183                 :            :                      If all the other args produce the same result,
    6184                 :            :                      we're still OK.  */
    6185                 :        421 :                   if (arg == gimple_phi_result (stmt))
    6186                 :          0 :                     continue;
    6187                 :        421 :                   else if (TREE_CODE (arg) == INTEGER_CST)
    6188                 :            :                     {
    6189                 :        344 :                       if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
    6190                 :            :                         {
    6191                 :        146 :                           if (!result)
    6192                 :        100 :                             result = boolean_true_node;
    6193                 :         46 :                           else if (!integer_onep (result))
    6194                 :            :                             return NULL_TREE;
    6195                 :            :                         }
    6196                 :        198 :                       else if (!result)
    6197                 :         46 :                         result = fold_build2 (code2, boolean_type_node,
    6198                 :            :                                               op2a, op2b);
    6199                 :        152 :                       else if (!same_bool_comparison_p (result,
    6200                 :            :                                                         code2, op2a, op2b))
    6201                 :            :                         return NULL_TREE;
    6202                 :            :                     }
    6203                 :         77 :                   else if (TREE_CODE (arg) == SSA_NAME
    6204                 :         77 :                            && !SSA_NAME_IS_DEFAULT_DEF (arg))
    6205                 :            :                     {
    6206                 :         77 :                       tree temp;
    6207                 :         77 :                       gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
    6208                 :            :                       /* In simple cases we can look through PHI nodes,
    6209                 :            :                          but we have to be careful with loops.
    6210                 :            :                          See PR49073.  */
    6211                 :         77 :                       if (! dom_info_available_p (CDI_DOMINATORS)
    6212                 :         77 :                           || gimple_bb (def_stmt) == gimple_bb (stmt)
    6213                 :        154 :                           || dominated_by_p (CDI_DOMINATORS,
    6214                 :         77 :                                              gimple_bb (def_stmt),
    6215                 :         77 :                                              gimple_bb (stmt)))
    6216                 :          0 :                         return NULL_TREE;
    6217                 :         77 :                       temp = or_var_with_comparison (type, arg, invert, code2,
    6218                 :            :                                                      op2a, op2b);
    6219                 :         77 :                       if (!temp)
    6220                 :            :                         return NULL_TREE;
    6221                 :          0 :                       else if (!result)
    6222                 :            :                         result = temp;
    6223                 :          0 :                       else if (!same_bool_result_p (result, temp))
    6224                 :            :                         return NULL_TREE;
    6225                 :            :                     }
    6226                 :            :                   else
    6227                 :            :                     return NULL_TREE;
    6228                 :            :                 }
    6229                 :          0 :               return result;
    6230                 :            :             }
    6231                 :            : 
    6232                 :            :         default:
    6233                 :            :           break;
    6234                 :            :         }
    6235                 :            :     }
    6236                 :            :   return NULL_TREE;
    6237                 :            : }
    6238                 :            : 
    6239                 :            : /* Try to simplify the OR of two comparisons, specified by
    6240                 :            :    (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
    6241                 :            :    If this can be simplified to a single expression (without requiring
    6242                 :            :    introducing more SSA variables to hold intermediate values),
    6243                 :            :    return the resulting tree.  Otherwise return NULL_TREE.
    6244                 :            :    If the result expression is non-null, it has boolean type.  */
    6245                 :            : 
    6246                 :            : tree
    6247                 :     152044 : maybe_fold_or_comparisons (tree type,
    6248                 :            :                            enum tree_code code1, tree op1a, tree op1b,
    6249                 :            :                            enum tree_code code2, tree op2a, tree op2b)
    6250                 :            : {
    6251                 :     152044 :   if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b))
    6252                 :            :     return t;
    6253                 :            : 
    6254                 :     151569 :   if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b))
    6255                 :            :     return t;
    6256                 :            : 
    6257                 :     151526 :   if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1,
    6258                 :            :                                                      op1a, op1b, code2, op2a,
    6259                 :            :                                                      op2b))
    6260                 :        151 :     return t;
    6261                 :            : 
    6262                 :            :   return NULL_TREE;
    6263                 :            : }
    6264                 :            : 
    6265                 :            : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
    6266                 :            : 
    6267                 :            :    Either NULL_TREE, a simplified but non-constant or a constant
    6268                 :            :    is returned.
    6269                 :            : 
    6270                 :            :    ???  This should go into a gimple-fold-inline.h file to be eventually
    6271                 :            :    privatized with the single valueize function used in the various TUs
    6272                 :            :    to avoid the indirect function call overhead.  */
    6273                 :            : 
    6274                 :            : tree
    6275                 :  266111000 : gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
    6276                 :            :                                 tree (*gvalueize) (tree))
    6277                 :            : {
    6278                 :  266111000 :   gimple_match_op res_op;
    6279                 :            :   /* ???  The SSA propagators do not correctly deal with following SSA use-def
    6280                 :            :      edges if there are intermediate VARYING defs.  For this reason
    6281                 :            :      do not follow SSA edges here even though SCCVN can technically
    6282                 :            :      just deal fine with that.  */
    6283                 :  266111000 :   if (gimple_simplify (stmt, &res_op, NULL, gvalueize, valueize))
    6284                 :            :     {
    6285                 :   30799700 :       tree res = NULL_TREE;
    6286                 :   30799700 :       if (gimple_simplified_result_is_gimple_val (&res_op))
    6287                 :   16755500 :         res = res_op.ops[0];
    6288                 :   14044300 :       else if (mprts_hook)
    6289                 :    4908770 :         res = mprts_hook (&res_op);
    6290                 :   21664200 :       if (res)
    6291                 :            :         {
    6292                 :   18112400 :           if (dump_file && dump_flags & TDF_DETAILS)
    6293                 :            :             {
    6294                 :        526 :               fprintf (dump_file, "Match-and-simplified ");
    6295                 :        526 :               print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
    6296                 :        526 :               fprintf (dump_file, " to ");
    6297                 :        526 :               print_generic_expr (dump_file, res);
    6298                 :        526 :               fprintf (dump_file, "\n");
    6299                 :            :             }
    6300                 :   18112400 :           return res;
    6301                 :            :         }
    6302                 :            :     }
    6303                 :            : 
    6304                 :  247998000 :   location_t loc = gimple_location (stmt);
    6305                 :  247998000 :   switch (gimple_code (stmt))
    6306                 :            :     {
    6307                 :  230544000 :     case GIMPLE_ASSIGN:
    6308                 :  230544000 :       {
    6309                 :  230544000 :         enum tree_code subcode = gimple_assign_rhs_code (stmt);
    6310                 :            : 
    6311                 :  230544000 :         switch (get_gimple_rhs_class (subcode))
    6312                 :            :           {
    6313                 :   81148700 :           case GIMPLE_SINGLE_RHS:
    6314                 :   81148700 :             {
    6315                 :   81148700 :               tree rhs = gimple_assign_rhs1 (stmt);
    6316                 :   81148700 :               enum tree_code_class kind = TREE_CODE_CLASS (subcode);
    6317                 :            : 
    6318                 :   81148700 :               if (TREE_CODE (rhs) == SSA_NAME)
    6319                 :            :                 {
    6320                 :            :                   /* If the RHS is an SSA_NAME, return its known constant value,
    6321                 :            :                      if any.  */
    6322                 :    6000420 :                   return (*valueize) (rhs);
    6323                 :            :                 }
    6324                 :            :               /* Handle propagating invariant addresses into address
    6325                 :            :                  operations.  */
    6326                 :   75148300 :               else if (TREE_CODE (rhs) == ADDR_EXPR
    6327                 :   75148300 :                        && !is_gimple_min_invariant (rhs))
    6328                 :            :                 {
    6329                 :    5952660 :                   poly_int64 offset = 0;
    6330                 :    5952660 :                   tree base;
    6331                 :    5952660 :                   base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (rhs, 0),
    6332                 :            :                                                           &offset,
    6333                 :            :                                                           valueize);
    6334                 :    5952660 :                   if (base
    6335                 :    5952660 :                       && (CONSTANT_CLASS_P (base)
    6336                 :    5494460 :                           || decl_address_invariant_p (base)))
    6337                 :      85963 :                     return build_invariant_address (TREE_TYPE (rhs),
    6338                 :      85963 :                                                     base, offset);
    6339                 :            :                 }
    6340                 :   69195600 :               else if (TREE_CODE (rhs) == CONSTRUCTOR
    6341                 :     381269 :                        && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
    6342                 :   69640100 :                        && known_eq (CONSTRUCTOR_NELTS (rhs),
    6343                 :            :                                     TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
    6344                 :            :                 {
    6345                 :      59235 :                   unsigned i, nelts;
    6346                 :      59235 :                   tree val;
    6347                 :            : 
    6348                 :      59235 :                   nelts = CONSTRUCTOR_NELTS (rhs);
    6349                 :     118470 :                   tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
    6350                 :     181940 :                   FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
    6351                 :            :                     {
    6352                 :      86742 :                       val = (*valueize) (val);
    6353                 :      86742 :                       if (TREE_CODE (val) == INTEGER_CST
    6354                 :      60883 :                           || TREE_CODE (val) == REAL_CST
    6355                 :      55007 :                           || TREE_CODE (val) == FIXED_CST)
    6356                 :      31735 :                         vec.quick_push (val);
    6357                 :            :                       else
    6358                 :            :                         return NULL_TREE;
    6359                 :            :                     }
    6360                 :            : 
    6361                 :       4228 :                   return vec.build ();
    6362                 :            :                 }
    6363                 :   75003100 :               if (subcode == OBJ_TYPE_REF)
    6364                 :            :                 {
    6365                 :     149615 :                   tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
    6366                 :            :                   /* If callee is constant, we can fold away the wrapper.  */
    6367                 :     149615 :                   if (is_gimple_min_invariant (val))
    6368                 :            :                     return val;
    6369                 :            :                 }
    6370                 :            : 
    6371                 :   75003000 :               if (kind == tcc_reference)
    6372                 :            :                 {
    6373                 :   43241900 :                   if ((TREE_CODE (rhs) == VIEW_CONVERT_EXPR
    6374                 :   41515700 :                        || TREE_CODE (rhs) == REALPART_EXPR
    6375                 :   40842100 :                        || TREE_CODE (rhs) == IMAGPART_EXPR)
    6376                 :   44873100 :                       && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
    6377                 :            :                     {
    6378                 :    2708040 :                       tree val = (*valueize) (TREE_OPERAND (rhs, 0));
    6379                 :    5416080 :                       return fold_unary_loc (EXPR_LOCATION (rhs),
    6380                 :            :                                              TREE_CODE (rhs),
    6381                 :    5416080 :                                              TREE_TYPE (rhs), val);
    6382                 :            :                     }
    6383                 :   40533900 :                   else if (TREE_CODE (rhs) == BIT_FIELD_REF
    6384                 :   40533900 :                            && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
    6385                 :            :                     {
    6386                 :     313544 :                       tree val = (*valueize) (TREE_OPERAND (rhs, 0));
    6387                 :     627088 :                       return fold_ternary_loc (EXPR_LOCATION (rhs),
    6388                 :            :                                                TREE_CODE (rhs),
    6389                 :     313544 :                                                TREE_TYPE (rhs), val,
    6390                 :     313544 :                                                TREE_OPERAND (rhs, 1),
    6391                 :     627088 :                                                TREE_OPERAND (rhs, 2));
    6392                 :            :                     }
    6393                 :   40220300 :                   else if (TREE_CODE (rhs) == MEM_REF
    6394                 :   40220300 :                            && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
    6395                 :            :                     {
    6396                 :    6757190 :                       tree val = (*valueize) (TREE_OPERAND (rhs, 0));
    6397                 :    6757190 :                       if (TREE_CODE (val) == ADDR_EXPR
    6398                 :    6757190 :                           && is_gimple_min_invariant (val))
    6399                 :            :                         {
    6400                 :     383786 :                           tree tem = fold_build2 (MEM_REF, TREE_TYPE (rhs),
    6401                 :            :                                                   unshare_expr (val),
    6402                 :            :                                                   TREE_OPERAND (rhs, 1));
    6403                 :     383786 :                           if (tem)
    6404                 :     383786 :                             rhs = tem;
    6405                 :            :                         }
    6406                 :            :                     }
    6407                 :   40220300 :                   return fold_const_aggregate_ref_1 (rhs, valueize);
    6408                 :            :                 }
    6409                 :   31761100 :               else if (kind == tcc_declaration)
    6410                 :    4864150 :                 return get_symbol_constant_value (rhs);
    6411                 :            :               return rhs;
    6412                 :            :             }
    6413                 :            : 
    6414                 :            :           case GIMPLE_UNARY_RHS:
    6415                 :            :             return NULL_TREE;
    6416                 :            : 
    6417                 :  108916000 :           case GIMPLE_BINARY_RHS:
    6418                 :            :             /* Translate &x + CST into an invariant form suitable for
    6419                 :            :                further propagation.  */
    6420                 :  108916000 :             if (subcode == POINTER_PLUS_EXPR)
    6421                 :            :               {
    6422                 :   10617000 :                 tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
    6423                 :   10617000 :                 tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
    6424                 :   10617000 :                 if (TREE_CODE (op0) == ADDR_EXPR
    6425                 :     813728 :                     && TREE_CODE (op1) == INTEGER_CST)
    6426                 :            :                   {
    6427                 :     291916 :                     tree off = fold_convert (ptr_type_node, op1);
    6428                 :     291916 :                     return build1_loc
    6429                 :     583832 :                         (loc, ADDR_EXPR, TREE_TYPE (op0),
    6430                 :     291916 :                          fold_build2 (MEM_REF,
    6431                 :            :                                       TREE_TYPE (TREE_TYPE (op0)),
    6432                 :            :                                       unshare_expr (op0), off));
    6433                 :            :                   }
    6434                 :            :               }
    6435                 :            :             /* Canonicalize bool != 0 and bool == 0 appearing after
    6436                 :            :                valueization.  While gimple_simplify handles this
    6437                 :            :                it can get confused by the ~X == 1 -> X == 0 transform
    6438                 :            :                which we cant reduce to a SSA name or a constant
    6439                 :            :                (and we have no way to tell gimple_simplify to not
    6440                 :            :                consider those transforms in the first place).  */
    6441                 :   98299000 :             else if (subcode == EQ_EXPR
    6442                 :   98299000 :                      || subcode == NE_EXPR)
    6443                 :            :               {
    6444                 :    3338150 :                 tree lhs = gimple_assign_lhs (stmt);
    6445                 :    3338150 :                 tree op0 = gimple_assign_rhs1 (stmt);
    6446                 :    3338150 :                 if (useless_type_conversion_p (TREE_TYPE (lhs),
    6447                 :    3338150 :                                                TREE_TYPE (op0)))
    6448                 :            :                   {
    6449                 :      29292 :                     tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
    6450                 :      29292 :                     op0 = (*valueize) (op0);
    6451                 :      29292 :                     if (TREE_CODE (op0) == INTEGER_CST)
    6452                 :       1456 :                       std::swap (op0, op1);
    6453                 :      29292 :                     if (TREE_CODE (op1) == INTEGER_CST
    6454                 :      29292 :                         && ((subcode == NE_EXPR && integer_zerop (op1))
    6455                 :       2667 :                             || (subcode == EQ_EXPR && integer_onep (op1))))
    6456                 :          7 :                       return op0;
    6457                 :            :                   }
    6458                 :            :               }
    6459                 :            :             return NULL_TREE;
    6460                 :            : 
    6461                 :     374736 :           case GIMPLE_TERNARY_RHS:
    6462                 :     374736 :             {
    6463                 :            :               /* Handle ternary operators that can appear in GIMPLE form.  */
    6464                 :     374736 :               tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
    6465                 :     374736 :               tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
    6466                 :     374736 :               tree op2 = (*valueize) (gimple_assign_rhs3 (stmt));
    6467                 :     374736 :               return fold_ternary_loc (loc, subcode,
    6468                 :     374736 :                                        gimple_expr_type (stmt), op0, op1, op2);
    6469                 :            :             }
    6470                 :            : 
    6471                 :          0 :           default:
    6472                 :          0 :             gcc_unreachable ();
    6473                 :            :           }
    6474                 :            :       }
    6475                 :            : 
    6476                 :   17016200 :     case GIMPLE_CALL:
    6477                 :   17016200 :       {
    6478                 :   17016200 :         tree fn;
    6479                 :   17016200 :         gcall *call_stmt = as_a <gcall *> (stmt);
    6480                 :            : 
    6481                 :   17016200 :         if (gimple_call_internal_p (stmt))
    6482                 :            :           {
    6483                 :     911943 :             enum tree_code subcode = ERROR_MARK;
    6484                 :     911943 :             switch (gimple_call_internal_fn (stmt))
    6485                 :            :               {
    6486                 :            :               case IFN_UBSAN_CHECK_ADD:
    6487                 :            :                 subcode = PLUS_EXPR;
    6488                 :            :                 break;
    6489                 :      19520 :               case IFN_UBSAN_CHECK_SUB:
    6490                 :      19520 :                 subcode = MINUS_EXPR;
    6491                 :      19520 :                 break;
    6492                 :      17365 :               case IFN_UBSAN_CHECK_MUL:
    6493                 :      17365 :                 subcode = MULT_EXPR;
    6494                 :      17365 :                 break;
    6495                 :      92373 :               case IFN_BUILTIN_EXPECT:
    6496                 :      92373 :                   {
    6497                 :      92373 :                     tree arg0 = gimple_call_arg (stmt, 0);
    6498                 :      92373 :                     tree op0 = (*valueize) (arg0);
    6499                 :      92373 :                     if (TREE_CODE (op0) == INTEGER_CST)
    6500                 :            :                       return op0;
    6501                 :      74244 :                     return NULL_TREE;
    6502                 :            :                   }
    6503                 :            :               default:
    6504                 :            :                 return NULL_TREE;
    6505                 :            :               }
    6506                 :      56543 :             tree arg0 = gimple_call_arg (stmt, 0);
    6507                 :      56543 :             tree arg1 = gimple_call_arg (stmt, 1);
    6508                 :      56543 :             tree op0 = (*valueize) (arg0);
    6509                 :      56543 :             tree op1 = (*valueize) (arg1);
    6510                 :            : 
    6511                 :      56543 :             if (TREE_CODE (op0) != INTEGER_CST
    6512                 :       8281 :                 || TREE_CODE (op1) != INTEGER_CST)
    6513                 :            :               {
    6514                 :      53564 :                 switch (subcode)
    6515                 :            :                   {
    6516                 :      16863 :                   case MULT_EXPR:
    6517                 :            :                     /* x * 0 = 0 * x = 0 without overflow.  */
    6518                 :      16863 :                     if (integer_zerop (op0) || integer_zerop (op1))
    6519                 :          0 :                       return build_zero_cst (TREE_TYPE (arg0));
    6520                 :            :                     break;
    6521                 :      18085 :                   case MINUS_EXPR:
    6522                 :            :                     /* y - y = 0 without overflow.  */
    6523                 :      18085 :                     if (operand_equal_p (op0, op1, 0))
    6524                 :          0 :                       return build_zero_cst (TREE_TYPE (arg0));
    6525                 :            :                     break;
    6526                 :            :                   default:
    6527                 :            :                     break;
    6528                 :            :                   }
    6529                 :            :               }
    6530                 :      56543 :             tree res
    6531                 :      56543 :               = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1);
    6532                 :      56543 :             if (res
    6533                 :      13266 :                 && TREE_CODE (res) == INTEGER_CST
    6534                 :      59522 :                 && !TREE_OVERFLOW (res))
    6535                 :       2073 :               return res;
    6536                 :            :             return NULL_TREE;
    6537                 :            :           }
    6538                 :            : 
    6539                 :   16104300 :         fn = (*valueize) (gimple_call_fn (stmt));
    6540                 :   16104300 :         if (TREE_CODE (fn) == ADDR_EXPR
    6541                 :   15255000 :             && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
    6542                 :   15254900 :             && fndecl_built_in_p (TREE_OPERAND (fn, 0))
    6543                 :   21278500 :             && gimple_builtin_call_types_compatible_p (stmt,
    6544                 :    5174230 :                                                        TREE_OPERAND (fn, 0)))
    6545                 :            :           {
    6546                 :    5108940 :             tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
    6547                 :    5108940 :             tree retval;
    6548                 :    5108940 :             unsigned i;
    6549                 :   15365500 :             for (i = 0; i < gimple_call_num_args (stmt); ++i)
    6550                 :   10256600 :               args[i] = (*valueize) (gimple_call_arg (stmt, i));
    6551                 :    5108940 :             retval = fold_builtin_call_array (loc,
    6552                 :            :                                          gimple_call_return_type (call_stmt),
    6553                 :            :                                          fn, gimple_call_num_args (stmt), args);
    6554                 :    5108940 :             if (retval)
    6555                 :            :               {
    6556                 :            :                 /* fold_call_expr wraps the result inside a NOP_EXPR.  */
    6557                 :      20355 :                 STRIP_NOPS (retval);
    6558                 :      20355 :                 retval = fold_convert (gimple_call_return_type (call_stmt),
    6559                 :            :                                        retval);
    6560                 :            :               }
    6561                 :    5108940 :             return retval;
    6562                 :            :           }
    6563                 :            :         return NULL_TREE;
    6564                 :            :       }
    6565                 :            : 
    6566                 :            :     default:
    6567                 :            :       return NULL_TREE;
    6568                 :            :     }
    6569                 :            : }
    6570                 :            : 
    6571                 :            : /* Fold STMT to a constant using VALUEIZE to valueize SSA names.
    6572                 :            :    Returns NULL_TREE if folding to a constant is not possible, otherwise
    6573                 :            :    returns a constant according to is_gimple_min_invariant.  */
    6574                 :            : 
    6575                 :            : tree
    6576                 :       4294 : gimple_fold_stmt_to_constant (gimple *stmt, tree (*valueize) (tree))
    6577                 :            : {
    6578                 :       4294 :   tree res = gimple_fold_stmt_to_constant_1 (stmt, valueize);
    6579                 :       4294 :   if (res && is_gimple_min_invariant (res))
    6580                 :       2267 :     return res;
    6581                 :            :   return NULL_TREE;
    6582                 :            : }
    6583                 :            : 
    6584                 :            : 
    6585                 :            : /* The following set of functions are supposed to fold references using
    6586                 :            :    their constant initializers.  */
    6587                 :            : 
    6588                 :            : /* See if we can find constructor defining value of BASE.
    6589                 :            :    When we know the consructor with constant offset (such as
    6590                 :            :    base is array[40] and we do know constructor of array), then
    6591                 :            :    BIT_OFFSET is adjusted accordingly.
    6592                 :            : 
    6593                 :            :    As a special case, return error_mark_node when constructor
    6594                 :            :    is not explicitly available, but it is known to be zero
    6595                 :            :    such as 'static const int a;'.  */
    6596                 :            : static tree
    6597                 :   88797100 : get_base_constructor (tree base, poly_int64_pod *bit_offset,
    6598                 :            :                       tree (*valueize)(tree))
    6599                 :            : {
    6600                 :   88797100 :   poly_int64 bit_offset2, size, max_size;
    6601                 :   88797100 :   bool reverse;
    6602                 :            : 
    6603                 :   88797100 :   if (TREE_CODE (base) == MEM_REF)
    6604                 :            :     {
    6605                 :   46768900 :       poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
    6606                 :   93537400 :       if (!boff.to_shwi (bit_offset))
    6607                 :   46619700 :         return NULL_TREE;
    6608                 :            : 
    6609                 :   46768500 :       if (valueize
    6610                 :   46768500 :           && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
    6611                 :   20977500 :         base = valueize (TREE_OPERAND (base, 0));
    6612                 :   46768500 :       if (!base || TREE_CODE (base) != ADDR_EXPR)
    6613                 :            :         return NULL_TREE;
    6614                 :     149233 :       base = TREE_OPERAND (base, 0);
    6615                 :            :     }
    6616                 :   42028200 :   else if (valueize
    6617                 :   18854700 :            && TREE_CODE (base) == SSA_NAME)
    6618                 :        195 :     base = valueize (base);
    6619                 :            : 
    6620                 :            :   /* Get a CONSTRUCTOR.  If BASE is a VAR_DECL, get its
    6621                 :            :      DECL_INITIAL.  If BASE is a nested reference into another
    6622                 :            :      ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
    6623                 :            :      the inner reference.  */
    6624                 :   42177500 :   switch (TREE_CODE (base))
    6625                 :            :     {
    6626                 :   37820800 :     case VAR_DECL:
    6627                 :   37820800 :     case CONST_DECL:
    6628                 :   37820800 :       {
    6629                 :   37820800 :         tree init = ctor_for_folding (base);
    6630                 :            : 
    6631                 :            :         /* Our semantic is exact opposite of ctor_for_folding;
    6632                 :            :            NULL means unknown, while error_mark_node is 0.  */
    6633                 :   37820800 :         if (init == error_mark_node)
    6634                 :            :           return NULL_TREE;
    6635                 :     637281 :         if (!init)
    6636                 :        950 :           return error_mark_node;
    6637                 :            :         return init;
    6638                 :            :       }
    6639                 :            : 
    6640                 :      46583 :     case VIEW_CONVERT_EXPR:
    6641                 :      46583 :       return get_base_constructor (TREE_OPERAND (base, 0),
    6642                 :      46583 :                                    bit_offset, valueize);
    6643                 :            : 
    6644                 :     203026 :     case ARRAY_REF:
    6645                 :     203026 :     case COMPONENT_REF:
    6646                 :     203026 :       base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
    6647                 :            :                                       &reverse);
    6648                 :     203026 :       if (!known_size_p (max_size) || maybe_ne (size, max_size))
    6649                 :            :         return NULL_TREE;
    6650                 :     143667 :       *bit_offset +=  bit_offset2;
    6651                 :     143667 :       return get_base_constructor (base, bit_offset, valueize);
    6652                 :            : 
    6653                 :            :     case CONSTRUCTOR:
    6654                 :            :       return base;
    6655                 :            : 
    6656                 :    4107090 :     default:
    6657                 :    4107090 :       if (CONSTANT_CLASS_P (base))
    6658                 :     214802 :         return base;
    6659                 :            : 
    6660                 :            :       return NULL_TREE;
    6661                 :            :     }
    6662                 :            : }
    6663                 :            : 
    6664                 :            : /* CTOR is CONSTRUCTOR of an array type.  Fold a reference of SIZE bits
    6665                 :            :    to the memory at bit OFFSET.     When non-null, TYPE is the expected
    6666                 :            :    type of the reference; otherwise the type of the referenced element
    6667                 :            :    is used instead. When SIZE is zero, attempt to fold a reference to
    6668                 :            :    the entire element which OFFSET refers to.  Increment *SUBOFF by
    6669                 :            :    the bit offset of the accessed element.  */
    6670                 :            : 
    6671                 :            : static tree
    6672                 :     500705 : fold_array_ctor_reference (tree type, tree ctor,
    6673                 :            :                            unsigned HOST_WIDE_INT offset,
    6674                 :            :                            unsigned HOST_WIDE_INT size,
    6675                 :            :                            tree from_decl,
    6676                 :            :                            unsigned HOST_WIDE_INT *suboff)
    6677                 :            : {
    6678                 :     500705 :   offset_int low_bound;
    6679                 :     500705 :   offset_int elt_size;
    6680                 :     500705 :   offset_int access_index;
    6681                 :     500705 :   tree domain_type = NULL_TREE;
    6682                 :     500705 :   HOST_WIDE_INT inner_offset;
    6683                 :            : 
    6684                 :            :   /* Compute low bound and elt size.  */
    6685                 :     500705 :   if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
    6686                 :     500705 :     domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
    6687                 :     500705 :   if (domain_type && TYPE_MIN_VALUE (domain_type))
    6688                 :            :     {
    6689                 :            :       /* Static constructors for variably sized objects make no sense.  */
    6690                 :     500705 :       if (TREE_CODE (TYPE_MIN_VALUE (domain_type)) != INTEGER_CST)
    6691                 :            :         return NULL_TREE;
    6692                 :     500705 :       low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
    6693                 :            :     }
    6694                 :            :   else
    6695                 :          0 :     low_bound = 0;
    6696                 :            :   /* Static constructors for variably sized objects make no sense.  */
    6697                 :     500705 :   if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))) != INTEGER_CST)
    6698                 :            :     return NULL_TREE;
    6699                 :     500705 :   elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
    6700                 :            : 
    6701                 :            :   /* When TYPE is non-null, verify that it specifies a constant-sized
    6702                 :            :      access of a multiple of the array element size.  Avoid division
    6703                 :            :      by zero below when ELT_SIZE is zero, such as with the result of
    6704                 :            :      an initializer for a zero-length array or an empty struct.  */
    6705                 :     500705 :   if (elt_size == 0
    6706                 :     500659 :       || (type
    6707                 :     500659 :           && (!TYPE_SIZE_UNIT (type)
    6708                 :     500659 :               || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
    6709                 :            :     return NULL_TREE;
    6710                 :            : 
    6711                 :            :   /* Compute the array index we look for.  */
    6712                 :    1001320 :   access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
    6713                 :     500659 :                                  elt_size);
    6714                 :     500659 :   access_index += low_bound;
    6715                 :            : 
    6716                 :            :   /* And offset within the access.  */
    6717                 :     500659 :   inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
    6718                 :            : 
    6719                 :     500659 :   unsigned HOST_WIDE_INT elt_sz = elt_size.to_uhwi ();
    6720                 :     500659 :   if (size > elt_sz * BITS_PER_UNIT)
    6721                 :            :     {
    6722                 :            :       /* native_encode_expr constraints.  */
    6723                 :      92586 :       if (size > MAX_BITSIZE_MODE_ANY_MODE
    6724                 :      89098 :           || size % BITS_PER_UNIT != 0
    6725                 :      89098 :           || inner_offset % BITS_PER_UNIT != 0
    6726                 :      89098 :           || elt_sz > MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT)
    6727                 :            :         return NULL_TREE;
    6728                 :            : 
    6729                 :      89098 :       unsigned ctor_idx;
    6730                 :      89098 :       tree val = get_array_ctor_element_at_index (ctor, access_index,
    6731                 :            :                                                   &ctor_idx);
    6732                 :      94673 :       if (!val && ctor_idx >= CONSTRUCTOR_NELTS  (ctor))
    6733                 :       2787 :         return build_zero_cst (type);
    6734                 :            : 
    6735                 :            :       /* native-encode adjacent ctor elements.  */
    6736                 :      86311 :       unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
    6737                 :      86311 :       unsigned bufoff = 0;
    6738                 :      86311 :       offset_int index = 0;
    6739                 :      86311 :       offset_int max_index = access_index;
    6740                 :      86311 :       constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
    6741                 :      86311 :       if (!val)
    6742                 :          1 :         val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
    6743                 :      86310 :       else if (!CONSTANT_CLASS_P (val))
    6744                 :            :         return NULL_TREE;
    6745                 :      41630 :       if (!elt->index)
    6746                 :            :         ;
    6747                 :      40509 :       else if (TREE_CODE (elt->index) == RANGE_EXPR)
    6748                 :            :         {
    6749                 :         22 :           index = wi::to_offset (TREE_OPERAND (elt->index, 0));
    6750                 :         22 :           max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
    6751                 :            :         }
    6752                 :            :       else
    6753                 :      40487 :         index = max_index = wi::to_offset (elt->index);
    6754                 :      41630 :       index = wi::umax (index, access_index);
    6755                 :     328751 :       do
    6756                 :            :         {
    6757                 :     328751 :           if (bufoff + elt_sz > sizeof (buf))
    6758                 :          8 :             elt_sz = sizeof (buf) - bufoff;
    6759                 :     657502 :           int len = native_encode_expr (val, buf + bufoff, elt_sz,
    6760                 :     328751 :                                         inner_offset / BITS_PER_UNIT);
    6761                 :     328751 :           if (len != (int) elt_sz - inner_offset / BITS_PER_UNIT)
    6762                 :            :             return NULL_TREE;
    6763                 :     328733 :           inner_offset = 0;
    6764                 :     328733 :           bufoff += len;
    6765                 :            : 
    6766                 :     328733 :           access_index += 1;
    6767                 :     328733 :           if (wi::cmpu (access_index, index) == 0)
    6768                 :          2 :             val = elt->value;
    6769                 :     328731 :           else if (wi::cmpu (access_index, max_index) > 0)
    6770                 :            :             {
    6771                 :     328473 :               ctor_idx++;
    6772                 :     656946 :               if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
    6773                 :            :                 {
    6774                 :     151602 :                   val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
    6775                 :     151602 :                   ++max_index;
    6776                 :            :                 }
    6777                 :            :               else
    6778                 :            :                 {
    6779                 :     176871 :                   elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
    6780                 :     176871 :                   index = 0;
    6781                 :     176871 :                   max_index = access_index;
    6782                 :     176871 :                   if (!elt->index)
    6783                 :            :                     ;
    6784                 :     176011 :                   else if (TREE_CODE (elt->index) == RANGE_EXPR)
    6785                 :            :                     {
    6786                 :          0 :                       index = wi::to_offset (TREE_OPERAND (elt->index, 0));
    6787                 :          0 :                       max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
    6788                 :            :                     }
    6789                 :            :                   else
    6790                 :     176011 :                     index = max_index = wi::to_offset (elt->index);
    6791                 :     176871 :                   index = wi::umax (index, access_index);
    6792                 :     176871 :                   if (wi::cmpu (access_index, index) == 0)
    6793                 :     176870 :                     val = elt->value;
    6794                 :            :                   else
    6795                 :          1 :                     val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
    6796                 :            :                 }
    6797                 :            :             }
    6798                 :            :         }
    6799                 :     328733 :       while (bufoff < size / BITS_PER_UNIT);
    6800                 :      41612 :       *suboff += size;
    6801                 :      41612 :       return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
    6802                 :            :     }
    6803                 :            : 
    6804                 :     408073 :   if (tree val = get_array_ctor_element_at_index (ctor, access_index))
    6805                 :            :     {
    6806                 :     407137 :       if (!size && TREE_CODE (val) != CONSTRUCTOR)
    6807                 :            :         {
    6808                 :            :           /* For the final reference to the entire accessed element
    6809                 :            :              (SIZE is zero), reset INNER_OFFSET, disegard TYPE (which
    6810                 :            :              may be null) in favor of the type of the element, and set
    6811                 :            :              SIZE to the size of the accessed element.  */
    6812                 :      31920 :           inner_offset = 0;
    6813                 :      31920 :           type = TREE_TYPE (val);
    6814                 :      31920 :           size = elt_size.to_uhwi () * BITS_PER_UNIT;
    6815                 :            :         }
    6816                 :            : 
    6817                 :     407137 :       *suboff += (access_index * elt_size * BITS_PER_UNIT).to_uhwi ();
    6818                 :     407137 :       return fold_ctor_reference (type, val, inner_offset, size, from_decl,
    6819                 :            :                                   suboff);
    6820                 :            :     }
    6821                 :            : 
    6822                 :            :   /* Memory not explicitly mentioned in constructor is 0 (or
    6823                 :            :      the reference is out of range).  */
    6824                 :        936 :   return type ? build_zero_cst (type) : NULL_TREE;
    6825                 :            : }
    6826                 :            : 
    6827                 :            : /* CTOR is CONSTRUCTOR of an aggregate or vector.  Fold a reference
    6828                 :            :    of SIZE bits to the memory at bit OFFSET.   When non-null, TYPE
    6829                 :            :    is the expected type of the reference; otherwise the type of
    6830                 :            :    the referenced member is used instead.  When SIZE is zero,
    6831                 :            :    attempt to fold a reference to the entire member which OFFSET
    6832                 :            :    refers to; in this case.  Increment *SUBOFF by the bit offset
    6833                 :            :    of the accessed member.  */
    6834                 :            : 
    6835                 :            : static tree
    6836                 :      73239 : fold_nonarray_ctor_reference (tree type, tree ctor,
    6837                 :            :                               unsigned HOST_WIDE_INT offset,
    6838                 :            :                               unsigned HOST_WIDE_INT size,
    6839                 :            :                               tree from_decl,
    6840                 :            :                               unsigned HOST_WIDE_INT *suboff)
    6841                 :            : {
    6842                 :      73239 :   unsigned HOST_WIDE_INT cnt;
    6843                 :      73239 :   tree cfield, cval;
    6844                 :            : 
    6845                 :     210790 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
    6846                 :            :                             cval)
    6847                 :            :     {
    6848                 :      98460 :       tree byte_offset = DECL_FIELD_OFFSET (cfield);
    6849                 :      98460 :       tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
    6850                 :      98460 :       tree field_size = DECL_SIZE (cfield);
    6851                 :            : 
    6852                 :      98460 :       if (!field_size)
    6853                 :            :         {
    6854                 :            :           /* Determine the size of the flexible array member from
    6855                 :            :              the size of the initializer provided for it.  */
    6856                 :        800 :           field_size = TYPE_SIZE (TREE_TYPE (cval));
    6857                 :            :         }
    6858                 :            : 
    6859                 :            :       /* Variable sized objects in static constructors makes no sense,
    6860                 :            :          but field_size can be NULL for flexible array members.  */
    6861                 :      98460 :       gcc_assert (TREE_CODE (field_offset) == INTEGER_CST
    6862                 :            :                   && TREE_CODE (byte_offset) == INTEGER_CST
    6863                 :            :                   && (field_size != NULL_TREE
    6864                 :            :                       ? TREE_CODE (field_size) == INTEGER_CST
    6865                 :            :                       : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
    6866                 :            : 
    6867                 :            :       /* Compute bit offset of the field.  */
    6868                 :      98460 :       offset_int bitoffset
    6869                 :      98460 :         = (wi::to_offset (field_offset)
    6870                 :      98460 :            + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
    6871                 :            :       /* Compute bit offset where the field ends.  */
    6872                 :      98460 :       offset_int bitoffset_end;
    6873                 :      98460 :       if (field_size != NULL_TREE)
    6874                 :      98460 :         bitoffset_end = bitoffset + wi::to_offset (field_size);
    6875                 :            :       else
    6876                 :          0 :         bitoffset_end = 0;
    6877                 :            : 
    6878                 :            :       /* Compute the bit offset of the end of the desired access.
    6879                 :            :          As a special case, if the size of the desired access is
    6880                 :            :          zero, assume the access is to the entire field (and let
    6881                 :            :          the caller make any necessary adjustments by storing
    6882                 :            :          the actual bounds of the field in FIELDBOUNDS).  */
    6883                 :      98460 :       offset_int access_end = offset_int (offset);
    6884                 :      98460 :       if (size)
    6885                 :      41126 :         access_end += size;
    6886                 :            :       else
    6887                 :      57334 :         access_end = bitoffset_end;
    6888                 :            : 
    6889                 :            :       /* Is there any overlap between the desired access at
    6890                 :            :          [OFFSET, OFFSET+SIZE) and the offset of the field within
    6891                 :            :          the object at [BITOFFSET, BITOFFSET_END)?  */
    6892                 :      98460 :       if (wi::cmps (access_end, bitoffset) > 0
    6893                 :      98460 :           && (field_size == NULL_TREE
    6894                 :      97686 :               || wi::lts_p (offset, bitoffset_end)))
    6895                 :            :         {
    6896                 :      64932 :           *suboff += bitoffset.to_uhwi ();
    6897                 :            : 
    6898                 :      64932 :           if (!size && TREE_CODE (cval) != CONSTRUCTOR)
    6899                 :            :             {
    6900                 :            :               /* For the final reference to the entire accessed member
    6901                 :            :                  (SIZE is zero), reset OFFSET, disegard TYPE (which may
    6902                 :            :                  be null) in favor of the type of the member, and set
    6903                 :            :                  SIZE to the size of the accessed member.  */
    6904                 :      31770 :               offset = bitoffset.to_uhwi ();
    6905                 :      31770 :               type = TREE_TYPE (cval);
    6906                 :      31770 :               size = (bitoffset_end - bitoffset).to_uhwi ();
    6907                 :            :             }
    6908                 :            : 
    6909                 :            :           /* We do have overlap.  Now see if the field is large enough
    6910                 :            :              to cover the access.  Give up for accesses that extend
    6911                 :            :              beyond the end of the object or that span multiple fields.  */
    6912                 :      64932 :           if (wi::cmps (access_end, bitoffset_end) > 0)
    6913                 :            :             return NULL_TREE;
    6914                 :      60280 :           if (offset < bitoffset)
    6915                 :            :             return NULL_TREE;
    6916                 :            : 
    6917                 :     120560 :           offset_int inner_offset = offset_int (offset) - bitoffset;
    6918                 :      60280 :           return fold_ctor_reference (type, cval,
    6919                 :      60280 :                                       inner_offset.to_uhwi (), size,
    6920                 :            :                                       from_decl, suboff);
    6921                 :            :         }
    6922                 :            :     }
    6923                 :            : 
    6924                 :       8307 :   if (!type)
    6925                 :            :     return NULL_TREE;
    6926                 :            : 
    6927                 :       8307 :   return build_zero_cst (type);
    6928                 :            : }
    6929                 :            : 
    6930                 :            : /* CTOR is value initializing memory.  Fold a reference of TYPE and
    6931                 :            :    bit size POLY_SIZE to the memory at bit POLY_OFFSET.  When POLY_SIZE
    6932                 :            :    is zero, attempt to fold a reference to the entire subobject
    6933                 :            :    which OFFSET refers to.  This is used when folding accesses to
    6934                 :            :    string members of aggregates.  When non-null, set *SUBOFF to
    6935                 :            :    the bit offset of the accessed subobject.  */
    6936                 :            : 
    6937                 :            : tree
    6938                 :    1223380 : fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
    6939                 :            :                      const poly_uint64 &poly_size, tree from_decl,
    6940                 :            :                      unsigned HOST_WIDE_INT *suboff /* = NULL */)
    6941                 :            : {
    6942                 :    1223380 :   tree ret;
    6943                 :            : 
    6944                 :            :   /* We found the field with exact match.  */
    6945                 :    1223380 :   if (type
    6946                 :    1223380 :       && useless_type_conversion_p (type, TREE_TYPE (ctor))
    6947                 :    1849430 :       && known_eq (poly_offset, 0U))
    6948                 :     420293 :     return canonicalize_constructor_val (unshare_expr (ctor), from_decl);
    6949                 :            : 
    6950                 :            :   /* The remaining optimizations need a constant size and offset.  */
    6951                 :     803088 :   unsigned HOST_WIDE_INT size, offset;
    6952                 :     803088 :   if (!poly_size.is_constant (&size) || !poly_offset.is_constant (&offset))
    6953                 :            :     return NULL_TREE;
    6954                 :            : 
    6955                 :            :   /* We are at the end of walk, see if we can view convert the
    6956                 :            :      result.  */
    6957                 :     891008 :   if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset
    6958                 :            :       /* VIEW_CONVERT_EXPR is defined only for matching sizes.  */
    6959                 :      12681 :       && !compare_tree_int (TYPE_SIZE (type), size)
    6960                 :     815612 :       && !compare_tree_int (TYPE_SIZE (TREE_TYPE (ctor)), size))
    6961                 :            :     {
    6962                 :      12131 :       ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl);
    6963                 :      12131 :       if (ret)
    6964                 :            :         {
    6965                 :      12131 :           ret = fold_unary (VIEW_CONVERT_EXPR, type, ret);
    6966                 :      12131 :           if (ret)
    6967                 :      12131 :             STRIP_USELESS_TYPE_CONVERSION (ret);
    6968                 :            :         }
    6969                 :      12131 :       return ret;
    6970                 :            :     }
    6971                 :            :   /* For constants and byte-aligned/sized reads try to go through
    6972                 :            :      native_encode/interpret.  */
    6973                 :     790957 :   if (CONSTANT_CLASS_P (ctor)
    6974                 :            :       && BITS_PER_UNIT == 8
    6975                 :     215545 :       && offset % BITS_PER_UNIT == 0
    6976                 :     215545 :       && offset / BITS_PER_UNIT <= INT_MAX
    6977                 :     215514 :       && size % BITS_PER_UNIT == 0
    6978                 :     215440 :       && size <= MAX_BITSIZE_MODE_ANY_MODE
    6979                 :    1006060 :       && can_native_interpret_type_p (type))
    6980                 :            :     {
    6981                 :      38540 :       unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
    6982                 :      77080 :       int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
    6983                 :      38540 :                                     offset / BITS_PER_UNIT);
    6984                 :      38540 :       if (len > 0)
    6985                 :      37361 :         return native_interpret_expr (type, buf, len);
    6986                 :            :     }
    6987                 :     753596 :   if (TREE_CODE (ctor) == CONSTRUCTOR)
    6988                 :            :     {
    6989                 :     573944 :       unsigned HOST_WIDE_INT dummy = 0;
    6990                 :     573944 :       if (!suboff)
    6991                 :     426600 :         suboff = &dummy;
    6992                 :            : 
    6993                 :     573944 :       tree ret;
    6994                 :     573944 :       if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE
    6995                 :     573944 :           || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE)
    6996                 :     500705 :         ret = fold_array_ctor_reference (type, ctor, offset, size,
    6997                 :            :                                          from_decl, suboff);
    6998                 :            :       else
    6999                 :      73239 :         ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
    7000                 :            :                                             from_decl, suboff);
    7001                 :            : 
    7002                 :            :       /* Fall back to native_encode_initializer.  Needs to be done
    7003                 :            :          only in the outermost fold_ctor_reference call (because it itself
    7004                 :            :          recurses into CONSTRUCTORs) and doesn't update suboff.  */
    7005                 :     573944 :       if (ret == NULL_TREE
    7006                 :     204522 :           && suboff == &dummy
    7007                 :            :           && BITS_PER_UNIT == 8
    7008                 :     202731 :           && offset % BITS_PER_UNIT == 0
    7009                 :     202095 :           && offset / BITS_PER_UNIT <= INT_MAX
    7010                 :     202095 :           && size % BITS_PER_UNIT == 0
    7011                 :     201393 :           && size <= MAX_BITSIZE_MODE_ANY_MODE
    7012                 :     771849 :           && can_native_interpret_type_p (type))
    7013                 :            :         {
    7014                 :     113229 :           unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
    7015                 :     226458 :           int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT,
    7016                 :     113229 :                                                offset / BITS_PER_UNIT);
    7017                 :     113229 :           if (len > 0)
    7018                 :        983 :             return native_interpret_expr (type, buf, len);
    7019                 :            :         }
    7020                 :            : 
    7021                 :     572961 :       return ret;
    7022                 :            :     }
    7023                 :            : 
    7024                 :            :   return NULL_TREE;
    7025                 :            : }
    7026                 :            : 
    7027                 :            : /* Return the tree representing the element referenced by T if T is an
    7028                 :            :    ARRAY_REF or COMPONENT_REF into constant aggregates valuezing SSA
    7029                 :            :    names using VALUEIZE.  Return NULL_TREE otherwise.  */
    7030                 :            : 
    7031                 :            : tree
    7032                 :  105770000 : fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
    7033                 :            : {
    7034                 :  105770000 :   tree ctor, idx, base;
    7035                 :  105770000 :   poly_int64 offset, size, max_size;
    7036                 :  105770000 :   tree tem;
    7037                 :  105770000 :   bool reverse;
    7038                 :            : 
    7039                 :  105770000 :   if (TREE_THIS_VOLATILE (t))
    7040                 :            :     return NULL_TREE;
    7041                 :            : 
    7042                 :  105377000 :   if (DECL_P (t))
    7043                 :   11534100 :     return get_symbol_constant_value (t);
    7044                 :            : 
    7045                 :   93842500 :   tem = fold_read_from_constant_string (t);
    7046                 :   93842500 :   if (tem)
    7047                 :            :     return tem;
    7048                 :            : 
    7049                 :   93838400 :   switch (TREE_CODE (t))
    7050                 :            :     {
    7051                 :    6829610 :     case ARRAY_REF:
    7052                 :    6829610 :     case ARRAY_RANGE_REF:
    7053                 :            :       /* Constant indexes are handled well by get_base_constructor.
    7054                 :            :          Only special case variable offsets.
    7055                 :            :          FIXME: This code can't handle nested references with variable indexes
    7056                 :            :          (they will be handled only by iteration of ccp).  Perhaps we can bring
    7057                 :            :          get_ref_base_and_extent here and make it use a valueize callback.  */
    7058                 :    6829610 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
    7059                 :    3941020 :           && valueize
    7060                 :    2567930 :           && (idx = (*valueize) (TREE_OPERAND (t, 1)))
    7061                 :    9397540 :           && poly_int_tree_p (idx))
    7062                 :            :         {
    7063                 :    1158310 :           tree low_bound, unit_size;
    7064                 :            : 
    7065                 :            :           /* If the resulting bit-offset is constant, track it.  */
    7066                 :    1158310 :           if ((low_bound = array_ref_low_bound (t),
    7067                 :    1158310 :                poly_int_tree_p (low_bound))
    7068                 :    1158310 :               && (unit_size = array_ref_element_size (t),
    7069                 :    1158310 :                   tree_fits_uhwi_p (unit_size)))
    7070                 :            :             {
    7071                 :    1158310 :               poly_offset_int woffset
    7072                 :    1158310 :                 = wi::sext (wi::to_poly_offset (idx)
    7073                 :    2316610 :                             - wi::to_poly_offset (low_bound),
    7074                 :    1158310 :                             TYPE_PRECISION (TREE_TYPE (idx)));
    7075                 :    1158310 :               woffset *= tree_to_uhwi (unit_size);
    7076                 :    1158310 :               woffset *= BITS_PER_UNIT;
    7077                 :    2316420 :               if (woffset.to_shwi (&offset))
    7078                 :            :                 {
    7079                 :    1158120 :                   base = TREE_OPERAND (t, 0);
    7080                 :    1158120 :                   ctor = get_base_constructor (base, &offset, valueize);
    7081                 :            :                   /* Empty constructor.  Always fold to 0.  */
    7082                 :    1158120 :                   if (ctor == error_mark_node)
    7083                 :    1158120 :                     return build_zero_cst (TREE_TYPE (t));
    7084                 :            :                   /* Out of bound array access.  Value is undefined,
    7085                 :            :                      but don't fold.  */
    7086                 :    1158030 :                   if (maybe_lt (offset, 0))
    7087                 :            :                     return NULL_TREE;
    7088                 :            :                   /* We cannot determine ctor.  */
    7089                 :    1157670 :                   if (!ctor)
    7090                 :            :                     return NULL_TREE;
    7091                 :      80487 :                   return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
    7092                 :      80487 :                                               tree_to_uhwi (unit_size)
    7093                 :      80487 :                                               * BITS_PER_UNIT,
    7094                 :            :                                               base);
    7095                 :            :                 }
    7096                 :            :             }
    7097                 :            :         }
    7098                 :            :       /* Fallthru.  */
    7099                 :            : 
    7100                 :   87448800 :     case COMPONENT_REF:
    7101                 :   87448800 :     case BIT_FIELD_REF:
    7102                 :   87448800 :     case TARGET_MEM_REF:
    7103                 :   87448800 :     case MEM_REF:
    7104                 :   87448800 :       base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
    7105                 :   87448800 :       ctor = get_base_constructor (base, &offset, valueize);
    7106                 :            : 
    7107                 :            :       /* Empty constructor.  Always fold to 0.  */
    7108                 :   87448800 :       if (ctor == error_mark_node)
    7109                 :        862 :         return build_zero_cst (TREE_TYPE (t));
    7110                 :            :       /* We do not know precise address.  */
    7111                 :   87447900 :       if (!known_size_p (max_size) || maybe_ne (max_size, size))
    7112                 :            :         return NULL_TREE;
    7113                 :            :       /* We cannot determine ctor.  */
    7114                 :   82760900 :       if (!ctor)
    7115                 :            :         return NULL_TREE;
    7116                 :            : 
    7117                 :            :       /* Out of bound array access.  Value is undefined, but don't fold.  */
    7118                 :     515516 :       if (maybe_lt (offset, 0))
    7119                 :            :         return NULL_TREE;
    7120                 :            : 
    7121                 :     515022 :       return fold_ctor_reference (TREE_TYPE (t), ctor, offset, size,
    7122                 :            :                                   base);
    7123                 :            : 
    7124                 :    1289190 :     case REALPART_EXPR:
    7125                 :    1289190 :     case IMAGPART_EXPR:
    7126                 :    1289190 :       {
    7127                 :    1289190 :         tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize);
    7128                 :    1289190 :         if (c && TREE_CODE (c) == COMPLEX_CST)
    7129                 :       1978 :           return fold_build1_loc (EXPR_LOCATION (t),
    7130                 :       1978 :                                   TREE_CODE (t), TREE_TYPE (t), c);
    7131                 :            :         break;
    7132                 :            :       }
    7133                 :            : 
    7134                 :            :     default:
    7135                 :            :       break;
    7136                 :            :     }
    7137                 :            : 
    7138                 :            :   return NULL_TREE;
    7139                 :            : }
    7140                 :            : 
    7141                 :            : tree
    7142                 :   64260800 : fold_const_aggregate_ref (tree t)
    7143                 :            : {
    7144                 :   64260800 :   return fold_const_aggregate_ref_1 (t, NULL);
    7145                 :            : }
    7146                 :            : 
    7147                 :            : /* Lookup virtual method with index TOKEN in a virtual table V
    7148                 :            :    at OFFSET.  
    7149                 :            :    Set CAN_REFER if non-NULL to false if method
    7150                 :            :    is not referable or if the virtual table is ill-formed (such as rewriten
    7151                 :            :    by non-C++ produced symbol). Otherwise just return NULL in that calse.  */
    7152                 :            : 
    7153                 :            : tree
    7154                 :     198614 : gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
    7155                 :            :                                    tree v,
    7156                 :            :                                    unsigned HOST_WIDE_INT offset,
    7157                 :            :                                    bool *can_refer)
    7158                 :            : {
    7159                 :     198614 :   tree vtable = v, init, fn;
    7160                 :     198614 :   unsigned HOST_WIDE_INT size;
    7161                 :     198614 :   unsigned HOST_WIDE_INT elt_size, access_index;
    7162                 :     198614 :   tree domain_type;
    7163                 :            : 
    7164                 :     198614 :   if (can_refer)
    7165                 :     198614 :     *can_refer = true;
    7166                 :            : 
    7167                 :            :   /* First of all double check we have virtual table.  */
    7168                 :     397228 :   if (!VAR_P (v) || !DECL_VIRTUAL_P (v))
    7169                 :            :     {
    7170                 :            :       /* Pass down that we lost track of the target.  */
    7171                 :          0 :       if (can_refer)
    7172                 :          0 :         *can_refer = false;
    7173                 :          0 :       return NULL_TREE;
    7174                 :            :     }
    7175                 :            : 
    7176                 :     198614 :   init = ctor_for_folding (v);
    7177                 :            : 
    7178                 :            :   /* The virtual tables should always be born with constructors
    7179                 :            :      and we always should assume that they are avaialble for
    7180                 :            :      folding.  At the moment we do not stream them in all cases,
    7181                 :            :      but it should never happen that ctor seem unreachable.  */
    7182                 :     198614 :   gcc_assert (init);
    7183                 :     198614 :   if (init == error_mark_node)
    7184                 :            :     {
    7185                 :            :       /* Pass down that we lost track of the target.  */
    7186                 :        158 :       if (can_refer)
    7187                 :        158 :         *can_refer = false;
    7188                 :        158 :       return NULL_TREE;
    7189                 :            :     }
    7190                 :     198456 :   gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
    7191                 :     198456 :   size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))));
    7192                 :     198456 :   offset *= BITS_PER_UNIT;
    7193                 :     198456 :   offset += token * size;
    7194                 :            : 
    7195                 :            :   /* Lookup the value in the constructor that is assumed to be array.
    7196                 :            :      This is equivalent to
    7197                 :            :      fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
    7198                 :            :                                offset, size, NULL);
    7199                 :            :      but in a constant time.  We expect that frontend produced a simple
    7200                 :            :      array without indexed initializers.  */
    7201                 :            : 
    7202                 :     198456 :   gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
    7203                 :     198456 :   domain_type = TYPE_DOMAIN (TREE_TYPE (init));
    7204                 :     198456 :   gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
    7205                 :     198456 :   elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
    7206                 :            : 
    7207                 :     198456 :   access_index = offset / BITS_PER_UNIT / elt_size;
    7208                 :     198456 :   gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);
    7209                 :            : 
    7210                 :            :   /* The C++ FE can now produce indexed fields, and we check if the indexes
    7211                 :            :      match.  */
    7212                 :     396912 :   if (access_index < CONSTRUCTOR_NELTS (init))
    7213                 :            :     {
    7214                 :     198455 :       fn = CONSTRUCTOR_ELT (init, access_index)->value;
    7215                 :     198455 :       tree idx = CONSTRUCTOR_ELT (init, access_index)->index;
    7216                 :     198455 :       gcc_checking_assert (!idx || tree_to_uhwi (idx) == access_index);
    7217                 :     198455 :       STRIP_NOPS (fn);
    7218                 :            :     }
    7219                 :            :   else
    7220                 :            :     fn = NULL;
    7221                 :            : 
    7222                 :            :   /* For type inconsistent program we may end up looking up virtual method
    7223                 :            :      in virtual table that does not contain TOKEN entries.  We may overrun
    7224                 :            :      the virtual table and pick up a constant or RTTI info pointer.
    7225                 :            :      In any case the call is undefined.  */
    7226                 :     198455 :   if (!fn
    7227                 :     198455 :       || (TREE_CODE (fn) != ADDR_EXPR && TREE_CODE (fn) != FDESC_EXPR)
    7228                 :     391795 :       || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
    7229                 :       5116 :     fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
    7230                 :            :   else
    7231                 :            :     {
    7232                 :     193340 :       fn = TREE_OPERAND (fn, 0);
    7233                 :            : 
    7234                 :            :       /* When cgraph node is missing and function is not public, we cannot
    7235                 :            :          devirtualize.  This can happen in WHOPR when the actual method
    7236                 :            :          ends up in other partition, because we found devirtualization
    7237                 :            :          possibility too late.  */
    7238                 :     193340 :       if (!can_refer_decl_in_current_unit_p (fn, vtable))
    7239                 :            :         {
    7240                 :      14992 :           if (can_refer)
    7241                 :            :             {
    7242                 :      14992 :               *can_refer = false;
    7243                 :      14992 :               return fn;
    7244                 :            :             }
    7245                 :            :           return NULL_TREE;
    7246                 :            :         }
    7247                 :            :     }
    7248                 :            : 
    7249                 :            :   /* Make sure we create a cgraph node for functions we'll reference.
    7250                 :            :      They can be non-existent if the reference comes from an entry
    7251                 :            :      of an external vtable for example.  */
    7252                 :     183464 :   cgraph_node::get_create (fn);
    7253                 :            : 
    7254                 :     183464 :   return fn;
    7255                 :            : }
    7256                 :            : 
    7257                 :            : /* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
    7258                 :            :    is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
    7259                 :            :    KNOWN_BINFO carries the binfo describing the true type of
    7260                 :            :    OBJ_TYPE_REF_OBJECT(REF).
    7261                 :            :    Set CAN_REFER if non-NULL to false if method
    7262                 :            :    is not referable or if the virtual table is ill-formed (such as rewriten
    7263                 :            :    by non-C++ produced symbol). Otherwise just return NULL in that calse.  */
    7264                 :            : 
    7265                 :            : tree
    7266                 :     196351 : gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
    7267                 :            :                                   bool *can_refer)
    7268                 :            : {
    7269                 :     196351 :   unsigned HOST_WIDE_INT offset;
    7270                 :     196351 :   tree v;
    7271                 :            : 
    7272                 :     196351 :   v = BINFO_VTABLE (known_binfo);
    7273                 :            :   /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone.  */
    7274                 :     196351 :   if (!v)
    7275                 :            :     return NULL_TREE;
    7276                 :            : 
    7277                 :     196351 :   if (!vtable_pointer_value_to_vtable (v, &v, &offset))
    7278                 :            :     {
    7279                 :          0 :       if (can_refer)
    7280                 :          0 :         *can_refer = false;
    7281                 :          0 :       return NULL_TREE;
    7282                 :            :     }
    7283                 :     196351 :   return gimple_get_virt_method_for_vtable (token, v, offset, can_refer);
    7284                 :            : }
    7285                 :            : 
    7286                 :            : /* Given a pointer value T, return a simplified version of an
    7287                 :            :    indirection through T, or NULL_TREE if no simplification is
    7288                 :            :    possible.  Note that the resulting type may be different from
    7289                 :            :    the type pointed to in the sense that it is still compatible
    7290                 :            :    from the langhooks point of view. */
    7291                 :            : 
    7292                 :            : tree
    7293                 :     672621 : gimple_fold_indirect_ref (tree t)
    7294                 :            : {
    7295                 :     672621 :   tree ptype = TREE_TYPE (t), type = TREE_TYPE (ptype);
    7296                 :     672621 :   tree sub = t;
    7297                 :     672621 :   tree subtype;
    7298                 :            : 
    7299                 :     672621 :   STRIP_NOPS (sub);
    7300                 :     672621 :   subtype = TREE_TYPE (sub);
    7301                 :     672621 :   if (!POINTER_TYPE_P (subtype)
    7302                 :    1344690 :       || TYPE_REF_CAN_ALIAS_ALL (ptype))
    7303                 :            :     return NULL_TREE;
    7304                 :            : 
    7305                 :     671174 :   if (TREE_CODE (sub) == ADDR_EXPR)
    7306                 :            :     {
    7307                 :      28647 :       tree op = TREE_OPERAND (sub, 0);
    7308                 :      28647 :       tree optype = TREE_TYPE (op);
    7309                 :            :       /* *&p => p */
    7310                 :      28647 :       if (useless_type_conversion_p (type, optype))
    7311                 :            :         return op;
    7312                 :            : 
    7313                 :            :       /* *(foo *)&fooarray => fooarray[0] */
    7314                 :        552 :       if (TREE_CODE (optype) == ARRAY_TYPE
    7315                 :         67 :           && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
    7316                 :        619 :           && useless_type_conversion_p (type, TREE_TYPE (optype)))
    7317                 :            :        {
    7318                 :         53 :          tree type_domain = TYPE_DOMAIN (optype);
    7319                 :         53 :          tree min_val = size_zero_node;
    7320                 :         53 :          if (type_domain && TYPE_MIN_VALUE (type_domain))
    7321                 :         53 :            min_val = TYPE_MIN_VALUE (type_domain);
    7322                 :         53 :          if (TREE_CODE (min_val) == INTEGER_CST)
    7323                 :         53 :            return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
    7324                 :            :        }
    7325                 :            :       /* *(foo *)&complexfoo => __real__ complexfoo */
    7326                 :        499 :       else if (TREE_CODE (optype) == COMPLEX_TYPE
    7327                 :        505 :                && useless_type_conversion_p (type, TREE_TYPE (optype)))
    7328                 :          4 :         return fold_build1 (REALPART_EXPR, type, op);
    7329                 :            :       /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
    7330                 :        495 :       else if (TREE_CODE (optype) == VECTOR_TYPE
    7331                 :        522 :                && useless_type_conversion_p (type, TREE_TYPE (optype)))
    7332                 :            :         {
    7333                 :         26 :           tree part_width = TYPE_SIZE (type);
    7334                 :         26 :           tree index = bitsize_int (0);
    7335                 :         26 :           return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
    7336                 :            :         }
    7337                 :            :     }
    7338                 :            : 
    7339                 :            :   /* *(p + CST) -> ...  */
    7340                 :     642996 :   if (TREE_CODE (sub) == POINTER_PLUS_EXPR
    7341                 :     642996 :       && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
    7342                 :            :     {
    7343                 :      32507 :       tree addr = TREE_OPERAND (sub, 0);
    7344                 :      32507 :       tree off = TREE_OPERAND (sub, 1);
    7345                 :      32507 :       tree addrtype;
    7346                 :            : 
    7347                 :      32507 :       STRIP_NOPS (addr);
    7348                 :      32507 :       addrtype = TREE_TYPE (addr);
    7349                 :            : 
    7350                 :            :       /* ((foo*)&vectorfoo)[1] -> BIT_FIELD_REF<vectorfoo,...> */
    7351                 :      32507 :       if (TREE_CODE (addr) == ADDR_EXPR
    7352                 :         90 :           && TREE_CODE (TREE_TYPE (addrtype)) == VECTOR_TYPE
    7353                 :         38 :           && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype)))
    7354                 :      32535 :           && tree_fits_uhwi_p (off))
    7355                 :            :         {
    7356                 :         28 :           unsigned HOST_WIDE_INT offset = tree_to_uhwi (off);
    7357                 :         28 :           tree part_width = TYPE_SIZE (type);
    7358                 :         28 :           unsigned HOST_WIDE_INT part_widthi
    7359                 :         28 :             = tree_to_shwi (part_width) / BITS_PER_UNIT;
    7360                 :         28 :           unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
    7361                 :         28 :           tree index = bitsize_int (indexi);
    7362                 :         28 :           if (known_lt (offset / part_widthi,
    7363                 :            :                         TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
    7364                 :         28 :             return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
    7365                 :            :                                 part_width, index);
    7366                 :            :         }
    7367                 :            : 
    7368                 :            :       /* ((foo*)&complexfoo)[1] -> __imag__ complexfoo */
    7369                 :      32479 :       if (TREE_CODE (addr) == ADDR_EXPR
    7370                 :         62 :           && TREE_CODE (TREE_TYPE (addrtype)) == COMPLEX_TYPE
    7371                 :      32480 :           && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype))))
    7372                 :            :         {
    7373                 :          1 :           tree size = TYPE_SIZE_UNIT (type);
    7374                 :          1 :           if (tree_int_cst_equal (size, off))
    7375                 :          1 :             return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (addr, 0));
    7376                 :            :         }
    7377                 :            : 
    7378                 :            :       /* *(p + CST) -> MEM_REF <p, CST>.  */
    7379                 :      32478 :       if (TREE_CODE (addr) != ADDR_EXPR
    7380                 :      32478 :           || DECL_P (TREE_OPERAND (addr, 0)))
    7381                 :      32459 :         return fold_build2 (MEM_REF, type,
    7382                 :            :                             addr,
    7383                 :            :                             wide_int_to_tree (ptype, wi::to_wide (off)));
    7384                 :            :     }
    7385                 :            : 
    7386                 :            :   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
    7387                 :     610508 :   if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
    7388                 :       1396 :       && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
    7389                 :     611888 :       && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
    7390                 :            :     {
    7391                 :          0 :       tree type_domain;
    7392                 :          0 :       tree min_val = size_zero_node;
    7393                 :          0 :       tree osub = sub;
    7394                 :          0 :       sub = gimple_fold_indirect_ref (sub);
    7395                 :          0 :       if (! sub)
    7396                 :          0 :         sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
    7397                 :          0 :       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
    7398                 :          0 :       if (type_domain && TYPE_MIN_VALUE (type_domain))
    7399                 :          0 :         min_val = TYPE_MIN_VALUE (type_domain);
    7400                 :          0 :       if (TREE_CODE (min_val) == INTEGER_CST)
    7401                 :          0 :         return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
    7402                 :            :     }
    7403                 :            : 
    7404                 :            :   return NULL_TREE;
    7405                 :            : }
    7406                 :            : 
    7407                 :            : /* Return true if CODE is an operation that when operating on signed
    7408                 :            :    integer types involves undefined behavior on overflow and the
    7409                 :            :    operation can be expressed with unsigned arithmetic.  */
    7410                 :            : 
    7411                 :            : bool
    7412                 :      94608 : arith_code_with_undefined_signed_overflow (tree_code code)
    7413                 :            : {
    7414                 :      94608 :   switch (code)
    7415                 :            :     {
    7416                 :            :     case ABS_EXPR:
    7417                 :            :     case PLUS_EXPR:
    7418                 :            :     case MINUS_EXPR:
    7419                 :            :     case MULT_EXPR:
    7420                 :            :     case NEGATE_EXPR:
    7421                 :            :     case POINTER_PLUS_EXPR:
    7422                 :            :       return true;
    7423                 :      48009 :     default:
    7424                 :      48009 :       return false;
    7425                 :            :     }
    7426                 :            : }
    7427                 :            : 
    7428                 :            : /* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
    7429                 :            :    operation that can be transformed to unsigned arithmetic by converting
    7430                 :            :    its operand, carrying out the operation in the corresponding unsigned
    7431                 :            :    type and converting the result back to the original type.
    7432                 :            : 
    7433                 :            :    Returns a sequence of statements that replace STMT and also contain
    7434                 :            :    a modified form of STMT itself.  */
    7435                 :            : 
    7436                 :            : gimple_seq
    7437                 :      25054 : rewrite_to_defined_overflow (gimple *stmt)
    7438                 :            : {
    7439                 :      25054 :   if (dump_file && (dump_flags & TDF_DETAILS))
    7440                 :            :     {
    7441                 :          3 :       fprintf (dump_file, "rewriting stmt with undefined signed "
    7442                 :            :                "overflow ");
    7443                 :          3 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    7444                 :            :     }
    7445                 :            : 
    7446                 :      25054 :   tree lhs = gimple_assign_lhs (stmt);
    7447                 :      25054 :   tree type = unsigned_type_for (TREE_TYPE (lhs));
    7448                 :      25054 :   gimple_seq stmts = NULL;
    7449                 :      25054 :   if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
    7450                 :          3 :     gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
    7451                 :            :   else
    7452                 :      74605 :     for (unsigned i = 1; i < gimple_num_ops (stmt); ++i)
    7453                 :            :       {
    7454                 :      49554 :         tree op = gimple_op (stmt, i);
    7455                 :      49554 :         op = gimple_convert (&stmts, type, op);
    7456                 :      49554 :         gimple_set_op (stmt, i, op);
    7457                 :            :       }
    7458                 :      25054 :   gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
    7459                 :      25054 :   if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
    7460                 :          0 :     gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
    7461                 :      25054 :   gimple_set_modified (stmt, true);
    7462                 :      25054 :   gimple_seq_add_stmt (&stmts, stmt);
    7463                 :      25054 :   gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
    7464                 :      25054 :   gimple_seq_add_stmt (&stmts, cvt);
    7465                 :            : 
    7466                 :      25054 :   return stmts;
    7467                 :            : }
    7468                 :            : 
    7469                 :            : 
    7470                 :            : /* The valueization hook we use for the gimple_build API simplification.
    7471                 :            :    This makes us match fold_buildN behavior by only combining with
    7472                 :            :    statements in the sequence(s) we are currently building.  */
    7473                 :            : 
    7474                 :            : static tree
    7475                 :    5967080 : gimple_build_valueize (tree op)
    7476                 :            : {
    7477                 :    5967080 :   if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL)
    7478                 :     587392 :     return op;
    7479                 :            :   return NULL_TREE;
    7480                 :            : }
    7481                 :            : 
    7482                 :            : /* Build the expression CODE OP0 of type TYPE with location LOC,
    7483                 :            :    simplifying it first if possible.  Returns the built
    7484                 :            :    expression value and appends statements possibly defining it
    7485                 :            :    to SEQ.  */
    7486                 :            : 
    7487                 :            : tree
    7488                 :     226638 : gimple_build (gimple_seq *seq, location_t loc,
    7489                 :            :               enum tree_code code, tree type, tree op0)
    7490                 :            : {
    7491                 :     226638 :   tree res = gimple_simplify (code, type, op0, seq, gimple_build_valueize);
    7492                 :     226638 :   if (!res)
    7493                 :            :     {
    7494                 :     203664 :       res = create_tmp_reg_or_ssa_name (type);
    7495                 :     203664 :       gimple *stmt;
    7496                 :     203664 :       if (code == REALPART_EXPR
    7497                 :            :           || code == IMAGPART_EXPR
    7498                 :     203664 :           || code == VIEW_CONVERT_EXPR)
    7499                 :       1673 :         stmt = gimple_build_assign (res, code, build1 (code, type, op0));
    7500                 :            :       else
    7501                 :     201991 :         stmt = gimple_build_assign (res, code, op0);
    7502                 :     203664 :       gimple_set_location (stmt, loc);
    7503                 :     203664 :       gimple_seq_add_stmt_without_update (seq, stmt);
    7504                 :            :     }
    7505                 :     226638 :   return res;
    7506                 :            : }
    7507                 :            : 
    7508                 :            : /* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
    7509                 :            :    simplifying it first if possible.  Returns the built
    7510                 :            :    expression value and appends statements possibly defining it
    7511                 :            :    to SEQ.  */
    7512                 :            : 
    7513                 :            : tree
    7514                 :     551576 : gimple_build (gimple_seq *seq, location_t loc,
    7515                 :            :               enum tree_code code, tree type, tree op0, tree op1)
    7516                 :            : {
    7517                 :     551576 :   tree res = gimple_simplify (code, type, op0, op1, seq, gimple_build_valueize);
    7518                 :     551576 :   if (!res)
    7519                 :            :     {
    7520                 :     531481 :       res = create_tmp_reg_or_ssa_name (type);
    7521                 :     531481 :       gimple *stmt = gimple_build_assign (res, code, op0, op1);
    7522                 :     531481 :       gimple_set_location (stmt, loc);
    7523                 :     531481 :       gimple_seq_add_stmt_without_update (seq, stmt);
    7524                 :            :     }
    7525                 :     551576 :   return res;
    7526                 :            : }
    7527                 :            : 
    7528                 :            : /* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
    7529                 :            :    simplifying it first if possible.  Returns the built
    7530                 :            :    expression value and appends statements possibly defining it
    7531                 :            :    to SEQ.  */
    7532                 :            : 
    7533                 :            : tree
    7534                 :      22268 : gimple_build (gimple_seq *seq, location_t loc,
    7535                 :            :               enum tree_code code, tree type, tree op0, tree op1, tree op2)
    7536                 :            : {
    7537                 :      22268 :   tree res = gimple_simplify (code, type, op0, op1, op2,
    7538                 :            :                               seq, gimple_build_valueize);
    7539                 :      22268 :   if (!res)
    7540                 :            :     {
    7541                 :      22039 :       res = create_tmp_reg_or_ssa_name (type);
    7542                 :      22039 :       gimple *stmt;
    7543                 :      22039 :       if (code == BIT_FIELD_REF)
    7544                 :      14202 :         stmt = gimple_build_assign (res, code,
    7545                 :            :                                     build3 (code, type, op0, op1, op2));
    7546                 :            :       else
    7547                 :       7837 :         stmt = gimple_build_assign (res, code, op0, op1, op2);
    7548                 :      22039 :       gimple_set_location (stmt, loc);
    7549                 :      22039 :       gimple_seq_add_stmt_without_update (seq, stmt);
    7550                 :            :     }
    7551                 :      22268 :   return res;
    7552                 :            : }
    7553                 :            : 
    7554                 :            : /* Build the call FN (ARG0) with a result of type TYPE
    7555                 :            :    (or no result if TYPE is void) with location LOC,
    7556                 :            :    simplifying it first if possible.  Returns the built
    7557                 :            :    expression value (or NULL_TREE if TYPE is void) and appends
    7558                 :            :    statements possibly defining it to SEQ.  */
    7559                 :            : 
    7560                 :            : tree
    7561                 :       6874 : gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
    7562                 :            :               tree type, tree arg0)
    7563                 :            : {
    7564                 :       6874 :   tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize);
    7565                 :       6874 :   if (!res)
    7566                 :            :     {
    7567                 :       6874 :       gcall *stmt;
    7568                 :       6874 :       if (internal_fn_p (fn))
    7569                 :       6874 :         stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
    7570                 :            :       else
    7571                 :            :         {
    7572                 :          0 :           tree decl = builtin_decl_implicit (as_builtin_fn (fn));
    7573                 :          0 :           stmt = gimple_build_call (decl, 1, arg0);
    7574                 :            :         }
    7575                 :       6874 :       if (!VOID_TYPE_P (type))
    7576                 :            :         {
    7577                 :       6874 :           res = create_tmp_reg_or_ssa_name (type);
    7578                 :       6874 :           gimple_call_set_lhs (stmt, res);