LCOV - code coverage report
Current view: top level - gcc - tree-ssa-math-opts.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.2 % 2888 2692
Test Date: 2025-03-15 13:07:15 Functions: 98.8 % 82 81
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Global, SSA-based optimizations using mathematical identities.
       2                 :             :    Copyright (C) 2005-2025 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it
       7                 :             : under the terms of the GNU General Public License as published by the
       8                 :             : Free Software Foundation; either version 3, or (at your option) any
       9                 :             : later version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT
      12                 :             : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : /* Currently, the only mini-pass in this file tries to CSE reciprocal
      21                 :             :    operations.  These are common in sequences such as this one:
      22                 :             : 
      23                 :             :         modulus = sqrt(x*x + y*y + z*z);
      24                 :             :         x = x / modulus;
      25                 :             :         y = y / modulus;
      26                 :             :         z = z / modulus;
      27                 :             : 
      28                 :             :    that can be optimized to
      29                 :             : 
      30                 :             :         modulus = sqrt(x*x + y*y + z*z);
      31                 :             :         rmodulus = 1.0 / modulus;
      32                 :             :         x = x * rmodulus;
      33                 :             :         y = y * rmodulus;
      34                 :             :         z = z * rmodulus;
      35                 :             : 
      36                 :             :    We do this for loop invariant divisors, and with this pass whenever
      37                 :             :    we notice that a division has the same divisor multiple times.
      38                 :             : 
      39                 :             :    Of course, like in PRE, we don't insert a division if a dominator
      40                 :             :    already has one.  However, this cannot be done as an extension of
      41                 :             :    PRE for several reasons.
      42                 :             : 
      43                 :             :    First of all, with some experiments it was found out that the
      44                 :             :    transformation is not always useful if there are only two divisions
      45                 :             :    by the same divisor.  This is probably because modern processors
      46                 :             :    can pipeline the divisions; on older, in-order processors it should
      47                 :             :    still be effective to optimize two divisions by the same number.
      48                 :             :    We make this a param, and it shall be called N in the remainder of
      49                 :             :    this comment.
      50                 :             : 
      51                 :             :    Second, if trapping math is active, we have less freedom on where
      52                 :             :    to insert divisions: we can only do so in basic blocks that already
      53                 :             :    contain one.  (If divisions don't trap, instead, we can insert
      54                 :             :    divisions elsewhere, which will be in blocks that are common dominators
      55                 :             :    of those that have the division).
      56                 :             : 
      57                 :             :    We really don't want to compute the reciprocal unless a division will
      58                 :             :    be found.  To do this, we won't insert the division in a basic block
      59                 :             :    that has less than N divisions *post-dominating* it.
      60                 :             : 
      61                 :             :    The algorithm constructs a subset of the dominator tree, holding the
      62                 :             :    blocks containing the divisions and the common dominators to them,
      63                 :             :    and walk it twice.  The first walk is in post-order, and it annotates
      64                 :             :    each block with the number of divisions that post-dominate it: this
      65                 :             :    gives information on where divisions can be inserted profitably.
      66                 :             :    The second walk is in pre-order, and it inserts divisions as explained
      67                 :             :    above, and replaces divisions by multiplications.
      68                 :             : 
      69                 :             :    In the best case, the cost of the pass is O(n_statements).  In the
      70                 :             :    worst-case, the cost is due to creating the dominator tree subset,
      71                 :             :    with a cost of O(n_basic_blocks ^ 2); however this can only happen
      72                 :             :    for n_statements / n_basic_blocks statements.  So, the amortized cost
      73                 :             :    of creating the dominator tree subset is O(n_basic_blocks) and the
      74                 :             :    worst-case cost of the pass is O(n_statements * n_basic_blocks).
      75                 :             : 
      76                 :             :    More practically, the cost will be small because there are few
      77                 :             :    divisions, and they tend to be in the same basic block, so insert_bb
      78                 :             :    is called very few times.
      79                 :             : 
      80                 :             :    If we did this using domwalk.cc, an efficient implementation would have
      81                 :             :    to work on all the variables in a single pass, because we could not
      82                 :             :    work on just a subset of the dominator tree, as we do now, and the
      83                 :             :    cost would also be something like O(n_statements * n_basic_blocks).
      84                 :             :    The data structures would be more complex in order to work on all the
      85                 :             :    variables in a single pass.  */
      86                 :             : 
      87                 :             : #include "config.h"
      88                 :             : #include "system.h"
      89                 :             : #include "coretypes.h"
      90                 :             : #include "backend.h"
      91                 :             : #include "target.h"
      92                 :             : #include "rtl.h"
      93                 :             : #include "tree.h"
      94                 :             : #include "gimple.h"
      95                 :             : #include "predict.h"
      96                 :             : #include "alloc-pool.h"
      97                 :             : #include "tree-pass.h"
      98                 :             : #include "ssa.h"
      99                 :             : #include "optabs-tree.h"
     100                 :             : #include "gimple-pretty-print.h"
     101                 :             : #include "alias.h"
     102                 :             : #include "fold-const.h"
     103                 :             : #include "gimple-iterator.h"
     104                 :             : #include "gimple-fold.h"
     105                 :             : #include "gimplify.h"
     106                 :             : #include "gimplify-me.h"
     107                 :             : #include "stor-layout.h"
     108                 :             : #include "tree-cfg.h"
     109                 :             : #include "tree-dfa.h"
     110                 :             : #include "tree-ssa.h"
     111                 :             : #include "builtins.h"
     112                 :             : #include "internal-fn.h"
     113                 :             : #include "case-cfn-macros.h"
     114                 :             : #include "optabs-libfuncs.h"
     115                 :             : #include "tree-eh.h"
     116                 :             : #include "targhooks.h"
     117                 :             : #include "domwalk.h"
     118                 :             : #include "tree-ssa-math-opts.h"
     119                 :             : #include "dbgcnt.h"
     120                 :             : #include "cfghooks.h"
     121                 :             : 
     122                 :             : /* This structure represents one basic block that either computes a
     123                 :             :    division, or is a common dominator for basic block that compute a
     124                 :             :    division.  */
     125                 :             : struct occurrence {
     126                 :             :   /* The basic block represented by this structure.  */
     127                 :             :   basic_block bb = basic_block();
     128                 :             : 
     129                 :             :   /* If non-NULL, the SSA_NAME holding the definition for a reciprocal
     130                 :             :      inserted in BB.  */
     131                 :             :   tree recip_def = tree();
     132                 :             : 
     133                 :             :   /* If non-NULL, the SSA_NAME holding the definition for a squared
     134                 :             :      reciprocal inserted in BB.  */
     135                 :             :   tree square_recip_def = tree();
     136                 :             : 
     137                 :             :   /* If non-NULL, the GIMPLE_ASSIGN for a reciprocal computation that
     138                 :             :      was inserted in BB.  */
     139                 :             :   gimple *recip_def_stmt = nullptr;
     140                 :             : 
     141                 :             :   /* Pointer to a list of "struct occurrence"s for blocks dominated
     142                 :             :      by BB.  */
     143                 :             :   struct occurrence *children = nullptr;
     144                 :             : 
     145                 :             :   /* Pointer to the next "struct occurrence"s in the list of blocks
     146                 :             :      sharing a common dominator.  */
     147                 :             :   struct occurrence *next = nullptr;
     148                 :             : 
     149                 :             :   /* The number of divisions that are in BB before compute_merit.  The
     150                 :             :      number of divisions that are in BB or post-dominate it after
     151                 :             :      compute_merit.  */
     152                 :             :   int num_divisions = 0;
     153                 :             : 
     154                 :             :   /* True if the basic block has a division, false if it is a common
     155                 :             :      dominator for basic blocks that do.  If it is false and trapping
     156                 :             :      math is active, BB is not a candidate for inserting a reciprocal.  */
     157                 :             :   bool bb_has_division = false;
     158                 :             : 
     159                 :             :   /* Construct a struct occurrence for basic block BB, and whose
     160                 :             :      children list is headed by CHILDREN.  */
     161                 :         618 :   occurrence (basic_block bb, struct occurrence *children)
     162                 :         618 :   : bb (bb), children (children)
     163                 :             :   {
     164                 :         618 :     bb->aux = this;
     165                 :             :   }
     166                 :             : 
     167                 :             :   /* Destroy a struct occurrence and remove it from its basic block.  */
     168                 :         618 :   ~occurrence ()
     169                 :             :   {
     170                 :         618 :     bb->aux = nullptr;
     171                 :         618 :   }
     172                 :             : 
     173                 :             :   /* Allocate memory for a struct occurrence from OCC_POOL.  */
     174                 :             :   static void* operator new (size_t);
     175                 :             : 
     176                 :             :   /* Return memory for a struct occurrence to OCC_POOL.  */
     177                 :             :   static void operator delete (void*, size_t);
     178                 :             : };
     179                 :             : 
     180                 :             : static struct
     181                 :             : {
     182                 :             :   /* Number of 1.0/X ops inserted.  */
     183                 :             :   int rdivs_inserted;
     184                 :             : 
     185                 :             :   /* Number of 1.0/FUNC ops inserted.  */
     186                 :             :   int rfuncs_inserted;
     187                 :             : } reciprocal_stats;
     188                 :             : 
     189                 :             : static struct
     190                 :             : {
     191                 :             :   /* Number of cexpi calls inserted.  */
     192                 :             :   int inserted;
     193                 :             : 
     194                 :             :   /* Number of conversions removed.  */
     195                 :             :   int conv_removed;
     196                 :             : 
     197                 :             : } sincos_stats;
     198                 :             : 
     199                 :             : static struct
     200                 :             : {
     201                 :             :   /* Number of widening multiplication ops inserted.  */
     202                 :             :   int widen_mults_inserted;
     203                 :             : 
     204                 :             :   /* Number of integer multiply-and-accumulate ops inserted.  */
     205                 :             :   int maccs_inserted;
     206                 :             : 
     207                 :             :   /* Number of fp fused multiply-add ops inserted.  */
     208                 :             :   int fmas_inserted;
     209                 :             : 
     210                 :             :   /* Number of divmod calls inserted.  */
     211                 :             :   int divmod_calls_inserted;
     212                 :             : 
     213                 :             :   /* Number of highpart multiplication ops inserted.  */
     214                 :             :   int highpart_mults_inserted;
     215                 :             : } widen_mul_stats;
     216                 :             : 
     217                 :             : /* The instance of "struct occurrence" representing the highest
     218                 :             :    interesting block in the dominator tree.  */
     219                 :             : static struct occurrence *occ_head;
     220                 :             : 
     221                 :             : /* Allocation pool for getting instances of "struct occurrence".  */
     222                 :             : static object_allocator<occurrence> *occ_pool;
     223                 :             : 
     224                 :         618 : void* occurrence::operator new (size_t n)
     225                 :             : {
     226                 :         618 :   gcc_assert (n == sizeof(occurrence));
     227                 :         618 :   return occ_pool->allocate_raw ();
     228                 :             : }
     229                 :             : 
     230                 :         618 : void occurrence::operator delete (void *occ, size_t n)
     231                 :             : {
     232                 :         618 :   gcc_assert (n == sizeof(occurrence));
     233                 :         618 :   occ_pool->remove_raw (occ);
     234                 :         618 : }
     235                 :             : 
     236                 :             : /* Insert NEW_OCC into our subset of the dominator tree.  P_HEAD points to a
     237                 :             :    list of "struct occurrence"s, one per basic block, having IDOM as
     238                 :             :    their common dominator.
     239                 :             : 
     240                 :             :    We try to insert NEW_OCC as deep as possible in the tree, and we also
     241                 :             :    insert any other block that is a common dominator for BB and one
     242                 :             :    block already in the tree.  */
     243                 :             : 
     244                 :             : static void
     245                 :         606 : insert_bb (struct occurrence *new_occ, basic_block idom,
     246                 :             :            struct occurrence **p_head)
     247                 :             : {
     248                 :         612 :   struct occurrence *occ, **p_occ;
     249                 :             : 
     250                 :         638 :   for (p_occ = p_head; (occ = *p_occ) != NULL; )
     251                 :             :     {
     252                 :          32 :       basic_block bb = new_occ->bb, occ_bb = occ->bb;
     253                 :          32 :       basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb);
     254                 :          32 :       if (dom == bb)
     255                 :             :         {
     256                 :             :           /* BB dominates OCC_BB.  OCC becomes NEW_OCC's child: remove OCC
     257                 :             :              from its list.  */
     258                 :           7 :           *p_occ = occ->next;
     259                 :           7 :           occ->next = new_occ->children;
     260                 :           7 :           new_occ->children = occ;
     261                 :             : 
     262                 :             :           /* Try the next block (it may as well be dominated by BB).  */
     263                 :             :         }
     264                 :             : 
     265                 :          25 :       else if (dom == occ_bb)
     266                 :             :         {
     267                 :             :           /* OCC_BB dominates BB.  Tail recurse to look deeper.  */
     268                 :           6 :           insert_bb (new_occ, dom, &occ->children);
     269                 :           6 :           return;
     270                 :             :         }
     271                 :             : 
     272                 :          19 :       else if (dom != idom)
     273                 :             :         {
     274                 :          12 :           gcc_assert (!dom->aux);
     275                 :             : 
     276                 :             :           /* There is a dominator between IDOM and BB, add it and make
     277                 :             :              two children out of NEW_OCC and OCC.  First, remove OCC from
     278                 :             :              its list.  */
     279                 :          12 :           *p_occ = occ->next;
     280                 :          12 :           new_occ->next = occ;
     281                 :          12 :           occ->next = NULL;
     282                 :             : 
     283                 :             :           /* None of the previous blocks has DOM as a dominator: if we tail
     284                 :             :              recursed, we would reexamine them uselessly. Just switch BB with
     285                 :             :              DOM, and go on looking for blocks dominated by DOM.  */
     286                 :          12 :           new_occ = new occurrence (dom, new_occ);
     287                 :             :         }
     288                 :             : 
     289                 :             :       else
     290                 :             :         {
     291                 :             :           /* Nothing special, go on with the next element.  */
     292                 :           7 :           p_occ = &occ->next;
     293                 :             :         }
     294                 :             :     }
     295                 :             : 
     296                 :             :   /* No place was found as a child of IDOM.  Make BB a sibling of IDOM.  */
     297                 :         606 :   new_occ->next = *p_head;
     298                 :         606 :   *p_head = new_occ;
     299                 :             : }
     300                 :             : 
     301                 :             : /* Register that we found a division in BB.
     302                 :             :    IMPORTANCE is a measure of how much weighting to give
     303                 :             :    that division.  Use IMPORTANCE = 2 to register a single
     304                 :             :    division.  If the division is going to be found multiple
     305                 :             :    times use 1 (as it is with squares).  */
     306                 :             : 
     307                 :             : static inline void
     308                 :         707 : register_division_in (basic_block bb, int importance)
     309                 :             : {
     310                 :         707 :   struct occurrence *occ;
     311                 :             : 
     312                 :         707 :   occ = (struct occurrence *) bb->aux;
     313                 :         707 :   if (!occ)
     314                 :             :     {
     315                 :         606 :       occ = new occurrence (bb, NULL);
     316                 :         606 :       insert_bb (occ, ENTRY_BLOCK_PTR_FOR_FN (cfun), &occ_head);
     317                 :             :     }
     318                 :             : 
     319                 :         707 :   occ->bb_has_division = true;
     320                 :         707 :   occ->num_divisions += importance;
     321                 :         707 : }
     322                 :             : 
     323                 :             : 
     324                 :             : /* Compute the number of divisions that postdominate each block in OCC and
     325                 :             :    its children.  */
     326                 :             : 
     327                 :             : static void
     328                 :          32 : compute_merit (struct occurrence *occ)
     329                 :             : {
     330                 :          32 :   struct occurrence *occ_child;
     331                 :          32 :   basic_block dom = occ->bb;
     332                 :             : 
     333                 :          61 :   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
     334                 :             :     {
     335                 :          29 :       basic_block bb;
     336                 :          29 :       if (occ_child->children)
     337                 :           5 :         compute_merit (occ_child);
     338                 :             : 
     339                 :          29 :       if (flag_exceptions)
     340                 :           6 :         bb = single_noncomplex_succ (dom);
     341                 :             :       else
     342                 :             :         bb = dom;
     343                 :             : 
     344                 :          29 :       if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb))
     345                 :          12 :         occ->num_divisions += occ_child->num_divisions;
     346                 :             :     }
     347                 :          32 : }
     348                 :             : 
     349                 :             : 
     350                 :             : /* Return whether USE_STMT is a floating-point division by DEF.  */
     351                 :             : static inline bool
     352                 :      323342 : is_division_by (gimple *use_stmt, tree def)
     353                 :             : {
     354                 :      323342 :   return is_gimple_assign (use_stmt)
     355                 :      214532 :          && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
     356                 :        1312 :          && gimple_assign_rhs2 (use_stmt) == def
     357                 :             :          /* Do not recognize x / x as valid division, as we are getting
     358                 :             :             confused later by replacing all immediate uses x in such
     359                 :             :             a stmt.  */
     360                 :         894 :          && gimple_assign_rhs1 (use_stmt) != def
     361                 :      324236 :          && !stmt_can_throw_internal (cfun, use_stmt);
     362                 :             : }
     363                 :             : 
     364                 :             : /* Return TRUE if USE_STMT is a multiplication of DEF by A.  */
     365                 :             : static inline bool
     366                 :      319496 : is_mult_by (gimple *use_stmt, tree def, tree a)
     367                 :             : {
     368                 :      319496 :   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
     369                 :      319496 :       && gimple_assign_rhs_code (use_stmt) == MULT_EXPR)
     370                 :             :     {
     371                 :       70982 :       tree op0 = gimple_assign_rhs1 (use_stmt);
     372                 :       70982 :       tree op1 = gimple_assign_rhs2 (use_stmt);
     373                 :             : 
     374                 :       70982 :       return (op0 == def && op1 == a)
     375                 :       70982 :               || (op0 == a && op1 == def);
     376                 :             :     }
     377                 :             :   return 0;
     378                 :             : }
     379                 :             : 
     380                 :             : /* Return whether USE_STMT is DEF * DEF.  */
     381                 :             : static inline bool
     382                 :      319451 : is_square_of (gimple *use_stmt, tree def)
     383                 :             : {
     384                 :           4 :   return is_mult_by (use_stmt, def, def);
     385                 :             : }
     386                 :             : 
     387                 :             : /* Return whether USE_STMT is a floating-point division by
     388                 :             :    DEF * DEF.  */
     389                 :             : static inline bool
     390                 :         186 : is_division_by_square (gimple *use_stmt, tree def)
     391                 :             : {
     392                 :         186 :   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
     393                 :         179 :       && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
     394                 :           7 :       && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
     395                 :         193 :       && !stmt_can_throw_internal (cfun, use_stmt))
     396                 :             :     {
     397                 :           7 :       tree denominator = gimple_assign_rhs2 (use_stmt);
     398                 :           7 :       if (TREE_CODE (denominator) == SSA_NAME)
     399                 :           7 :         return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
     400                 :             :     }
     401                 :             :   return 0;
     402                 :             : }
     403                 :             : 
     404                 :             : /* Walk the subset of the dominator tree rooted at OCC, setting the
     405                 :             :    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
     406                 :             :    the given basic block.  The field may be left NULL, of course,
     407                 :             :    if it is not possible or profitable to do the optimization.
     408                 :             : 
     409                 :             :    DEF_BSI is an iterator pointing at the statement defining DEF.
     410                 :             :    If RECIP_DEF is set, a dominator already has a computation that can
     411                 :             :    be used.
     412                 :             : 
     413                 :             :    If should_insert_square_recip is set, then this also inserts
     414                 :             :    the square of the reciprocal immediately after the definition
     415                 :             :    of the reciprocal.  */
     416                 :             : 
     417                 :             : static void
     418                 :          56 : insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
     419                 :             :                     tree def, tree recip_def, tree square_recip_def,
     420                 :             :                     int should_insert_square_recip, int threshold)
     421                 :             : {
     422                 :          56 :   tree type;
     423                 :          56 :   gassign *new_stmt, *new_square_stmt;
     424                 :          56 :   gimple_stmt_iterator gsi;
     425                 :          56 :   struct occurrence *occ_child;
     426                 :             : 
     427                 :          56 :   if (!recip_def
     428                 :          40 :       && (occ->bb_has_division || !flag_trapping_math)
     429                 :             :       /* Divide by two as all divisions are counted twice in
     430                 :             :          the costing loop.  */
     431                 :          36 :       && occ->num_divisions / 2 >= threshold)
     432                 :             :     {
     433                 :             :       /* Make a variable with the replacement and substitute it.  */
     434                 :          25 :       type = TREE_TYPE (def);
     435                 :          25 :       recip_def = create_tmp_reg (type, "reciptmp");
     436                 :          25 :       new_stmt = gimple_build_assign (recip_def, RDIV_EXPR,
     437                 :             :                                       build_one_cst (type), def);
     438                 :             : 
     439                 :          25 :       if (should_insert_square_recip)
     440                 :             :         {
     441                 :           4 :           square_recip_def = create_tmp_reg (type, "powmult_reciptmp");
     442                 :           4 :           new_square_stmt = gimple_build_assign (square_recip_def, MULT_EXPR,
     443                 :             :                                                  recip_def, recip_def);
     444                 :             :         }
     445                 :             : 
     446                 :          25 :       if (occ->bb_has_division)
     447                 :             :         {
     448                 :             :           /* Case 1: insert before an existing division.  */
     449                 :          22 :           gsi = gsi_after_labels (occ->bb);
     450                 :         207 :           while (!gsi_end_p (gsi)
     451                 :         207 :                  && (!is_division_by (gsi_stmt (gsi), def))
     452                 :         393 :                  && (!is_division_by_square (gsi_stmt (gsi), def)))
     453                 :         185 :             gsi_next (&gsi);
     454                 :             : 
     455                 :          22 :           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
     456                 :          22 :           if (should_insert_square_recip)
     457                 :           3 :             gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
     458                 :             :         }
     459                 :           3 :       else if (def_gsi && occ->bb == gsi_bb (*def_gsi))
     460                 :             :         {
     461                 :             :           /* Case 2: insert right after the definition.  Note that this will
     462                 :             :              never happen if the definition statement can throw, because in
     463                 :             :              that case the sole successor of the statement's basic block will
     464                 :             :              dominate all the uses as well.  */
     465                 :           2 :           gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
     466                 :           2 :           if (should_insert_square_recip)
     467                 :           1 :             gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT);
     468                 :             :         }
     469                 :             :       else
     470                 :             :         {
     471                 :             :           /* Case 3: insert in a basic block not containing defs/uses.  */
     472                 :           1 :           gsi = gsi_after_labels (occ->bb);
     473                 :           1 :           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
     474                 :           1 :           if (should_insert_square_recip)
     475                 :           0 :             gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
     476                 :             :         }
     477                 :             : 
     478                 :          25 :       reciprocal_stats.rdivs_inserted++;
     479                 :             : 
     480                 :          25 :       occ->recip_def_stmt = new_stmt;
     481                 :             :     }
     482                 :             : 
     483                 :          56 :   occ->recip_def = recip_def;
     484                 :          56 :   occ->square_recip_def = square_recip_def;
     485                 :          85 :   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
     486                 :          29 :     insert_reciprocals (def_gsi, occ_child, def, recip_def,
     487                 :             :                         square_recip_def, should_insert_square_recip,
     488                 :             :                         threshold);
     489                 :          56 : }
     490                 :             : 
     491                 :             : /* Replace occurrences of expr / (x * x) with expr * ((1 / x) * (1 / x)).
     492                 :             :    Take as argument the use for (x * x).  */
     493                 :             : static inline void
     494                 :           4 : replace_reciprocal_squares (use_operand_p use_p)
     495                 :             : {
     496                 :           4 :   gimple *use_stmt = USE_STMT (use_p);
     497                 :           4 :   basic_block bb = gimple_bb (use_stmt);
     498                 :           4 :   struct occurrence *occ = (struct occurrence *) bb->aux;
     499                 :             : 
     500                 :           8 :   if (optimize_bb_for_speed_p (bb) && occ->square_recip_def
     501                 :           8 :       && occ->recip_def)
     502                 :             :     {
     503                 :           4 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
     504                 :           4 :       gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
     505                 :           4 :       gimple_assign_set_rhs2 (use_stmt, occ->square_recip_def);
     506                 :           4 :       SET_USE (use_p, occ->square_recip_def);
     507                 :           4 :       fold_stmt_inplace (&gsi);
     508                 :           4 :       update_stmt (use_stmt);
     509                 :             :     }
     510                 :           4 : }
     511                 :             : 
     512                 :             : 
     513                 :             : /* Replace the division at USE_P with a multiplication by the reciprocal, if
     514                 :             :    possible.  */
     515                 :             : 
     516                 :             : static inline void
     517                 :         119 : replace_reciprocal (use_operand_p use_p)
     518                 :             : {
     519                 :         119 :   gimple *use_stmt = USE_STMT (use_p);
     520                 :         119 :   basic_block bb = gimple_bb (use_stmt);
     521                 :         119 :   struct occurrence *occ = (struct occurrence *) bb->aux;
     522                 :             : 
     523                 :         119 :   if (optimize_bb_for_speed_p (bb)
     524                 :         119 :       && occ->recip_def && use_stmt != occ->recip_def_stmt)
     525                 :             :     {
     526                 :          83 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
     527                 :          83 :       gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
     528                 :          83 :       SET_USE (use_p, occ->recip_def);
     529                 :          83 :       fold_stmt_inplace (&gsi);
     530                 :          83 :       update_stmt (use_stmt);
     531                 :             :     }
     532                 :         119 : }
     533                 :             : 
     534                 :             : 
     535                 :             : /* Free OCC and return one more "struct occurrence" to be freed.  */
     536                 :             : 
     537                 :             : static struct occurrence *
     538                 :         618 : free_bb (struct occurrence *occ)
     539                 :             : {
     540                 :         618 :   struct occurrence *child, *next;
     541                 :             : 
     542                 :             :   /* First get the two pointers hanging off OCC.  */
     543                 :         618 :   next = occ->next;
     544                 :         618 :   child = occ->children;
     545                 :         618 :   delete occ;
     546                 :             : 
     547                 :             :   /* Now ensure that we don't recurse unless it is necessary.  */
     548                 :         618 :   if (!child)
     549                 :             :     return next;
     550                 :             :   else
     551                 :             :     {
     552                 :          24 :       while (next)
     553                 :           3 :         next = free_bb (next);
     554                 :             : 
     555                 :             :       return child;
     556                 :             :     }
     557                 :             : }
     558                 :             : 
     559                 :             : /* Transform sequences like
     560                 :             :    t = sqrt (a)
     561                 :             :    x = 1.0 / t;
     562                 :             :    r1 = x * x;
     563                 :             :    r2 = a * x;
     564                 :             :    into:
     565                 :             :    t = sqrt (a)
     566                 :             :    r1 = 1.0 / a;
     567                 :             :    r2 = t;
     568                 :             :    x = r1 * r2;
     569                 :             :    depending on the uses of x, r1, r2.  This removes one multiplication and
     570                 :             :    allows the sqrt and division operations to execute in parallel.
     571                 :             :    DEF_GSI is the gsi of the initial division by sqrt that defines
     572                 :             :    DEF (x in the example above).  */
     573                 :             : 
     574                 :             : static void
     575                 :         566 : optimize_recip_sqrt (gimple_stmt_iterator *def_gsi, tree def)
     576                 :             : {
     577                 :         566 :   gimple *use_stmt;
     578                 :         566 :   imm_use_iterator use_iter;
     579                 :         566 :   gimple *stmt = gsi_stmt (*def_gsi);
     580                 :         566 :   tree x = def;
     581                 :         566 :   tree orig_sqrt_ssa_name = gimple_assign_rhs2 (stmt);
     582                 :         566 :   tree div_rhs1 = gimple_assign_rhs1 (stmt);
     583                 :             : 
     584                 :         566 :   if (TREE_CODE (orig_sqrt_ssa_name) != SSA_NAME
     585                 :         561 :       || TREE_CODE (div_rhs1) != REAL_CST
     586                 :         730 :       || !real_equal (&TREE_REAL_CST (div_rhs1), &dconst1))
     587                 :         476 :     return;
     588                 :             : 
     589                 :          90 :   gcall *sqrt_stmt
     590                 :         596 :     = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (orig_sqrt_ssa_name));
     591                 :             : 
     592                 :          42 :   if (!sqrt_stmt || !gimple_call_lhs (sqrt_stmt))
     593                 :             :     return;
     594                 :             : 
     595                 :          42 :   switch (gimple_call_combined_fn (sqrt_stmt))
     596                 :             :     {
     597                 :          31 :     CASE_CFN_SQRT:
     598                 :          31 :     CASE_CFN_SQRT_FN:
     599                 :          31 :       break;
     600                 :             : 
     601                 :             :     default:
     602                 :             :       return;
     603                 :             :     }
     604                 :          31 :   tree a = gimple_call_arg (sqrt_stmt, 0);
     605                 :             : 
     606                 :             :   /* We have 'a' and 'x'.  Now analyze the uses of 'x'.  */
     607                 :             : 
     608                 :             :   /* Statements that use x in x * x.  */
     609                 :          43 :   auto_vec<gimple *> sqr_stmts;
     610                 :             :   /* Statements that use x in a * x.  */
     611                 :          12 :   auto_vec<gimple *> mult_stmts;
     612                 :          31 :   bool has_other_use = false;
     613                 :          31 :   bool mult_on_main_path = false;
     614                 :             : 
     615                 :          89 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, x)
     616                 :             :     {
     617                 :          58 :       if (is_gimple_debug (use_stmt))
     618                 :           1 :         continue;
     619                 :          57 :       if (is_square_of (use_stmt, x))
     620                 :             :         {
     621                 :          12 :           sqr_stmts.safe_push (use_stmt);
     622                 :          12 :           if (gimple_bb (use_stmt) == gimple_bb (stmt))
     623                 :          17 :             mult_on_main_path = true;
     624                 :             :         }
     625                 :          45 :       else if (is_mult_by (use_stmt, x, a))
     626                 :             :         {
     627                 :          14 :           mult_stmts.safe_push (use_stmt);
     628                 :          14 :           if (gimple_bb (use_stmt) == gimple_bb (stmt))
     629                 :          17 :             mult_on_main_path = true;
     630                 :             :         }
     631                 :             :       else
     632                 :             :         has_other_use = true;
     633                 :          31 :     }
     634                 :             : 
     635                 :             :   /* In the x * x and a * x cases we just rewire stmt operands or
     636                 :             :      remove multiplications.  In the has_other_use case we introduce
     637                 :             :      a multiplication so make sure we don't introduce a multiplication
     638                 :             :      on a path where there was none.  */
     639                 :          31 :   if (has_other_use && !mult_on_main_path)
     640                 :          19 :     return;
     641                 :             : 
     642                 :          12 :   if (sqr_stmts.is_empty () && mult_stmts.is_empty ())
     643                 :             :     return;
     644                 :             : 
     645                 :             :   /* If x = 1.0 / sqrt (a) has uses other than those optimized here we want
     646                 :             :      to be able to compose it from the sqr and mult cases.  */
     647                 :          41 :   if (has_other_use && (sqr_stmts.is_empty () || mult_stmts.is_empty ()))
     648                 :             :     return;
     649                 :             : 
     650                 :          12 :   if (dump_file)
     651                 :             :     {
     652                 :          10 :       fprintf (dump_file, "Optimizing reciprocal sqrt multiplications of\n");
     653                 :          10 :       print_gimple_stmt (dump_file, sqrt_stmt, 0, TDF_NONE);
     654                 :          10 :       print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     655                 :          10 :       fprintf (dump_file, "\n");
     656                 :             :     }
     657                 :             : 
     658                 :          12 :   bool delete_div = !has_other_use;
     659                 :          12 :   tree sqr_ssa_name = NULL_TREE;
     660                 :          12 :   if (!sqr_stmts.is_empty ())
     661                 :             :     {
     662                 :             :       /* r1 = x * x.  Transform the original
     663                 :             :          x = 1.0 / t
     664                 :             :          into
     665                 :             :          tmp1 = 1.0 / a
     666                 :             :          r1 = tmp1.  */
     667                 :             : 
     668                 :          10 :       sqr_ssa_name
     669                 :          10 :         = make_temp_ssa_name (TREE_TYPE (a), NULL, "recip_sqrt_sqr");
     670                 :             : 
     671                 :          10 :       if (dump_file)
     672                 :             :         {
     673                 :          10 :           fprintf (dump_file, "Replacing original division\n");
     674                 :          10 :           print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     675                 :          10 :           fprintf (dump_file, "with new division\n");
     676                 :             :         }
     677                 :          10 :       stmt
     678                 :          10 :         = gimple_build_assign (sqr_ssa_name, gimple_assign_rhs_code (stmt),
     679                 :             :                                gimple_assign_rhs1 (stmt), a);
     680                 :          10 :       gsi_insert_before (def_gsi, stmt, GSI_SAME_STMT);
     681                 :          10 :       gsi_remove (def_gsi, true);
     682                 :          10 :       *def_gsi = gsi_for_stmt (stmt);
     683                 :          10 :       fold_stmt_inplace (def_gsi);
     684                 :          10 :       update_stmt (stmt);
     685                 :             : 
     686                 :          10 :       if (dump_file)
     687                 :          10 :         print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     688                 :             : 
     689                 :          20 :       delete_div = false;
     690                 :             :       gimple *sqr_stmt;
     691                 :             :       unsigned int i;
     692                 :          20 :       FOR_EACH_VEC_ELT (sqr_stmts, i, sqr_stmt)
     693                 :             :         {
     694                 :          10 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (sqr_stmt);
     695                 :          10 :           gimple_assign_set_rhs_from_tree (&gsi2, sqr_ssa_name);
     696                 :          10 :           update_stmt (sqr_stmt);
     697                 :             :         }
     698                 :             :     }
     699                 :          12 :   if (!mult_stmts.is_empty ())
     700                 :             :     {
     701                 :             :       /* r2 = a * x.  Transform this into:
     702                 :             :          r2 = t (The original sqrt (a)).  */
     703                 :             :       unsigned int i;
     704                 :          24 :       gimple *mult_stmt = NULL;
     705                 :          24 :       FOR_EACH_VEC_ELT (mult_stmts, i, mult_stmt)
     706                 :             :         {
     707                 :          12 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (mult_stmt);
     708                 :             : 
     709                 :          12 :           if (dump_file)
     710                 :             :             {
     711                 :          10 :               fprintf (dump_file, "Replacing squaring multiplication\n");
     712                 :          10 :               print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
     713                 :          10 :               fprintf (dump_file, "with assignment\n");
     714                 :             :             }
     715                 :          12 :           gimple_assign_set_rhs_from_tree (&gsi2, orig_sqrt_ssa_name);
     716                 :          12 :           fold_stmt_inplace (&gsi2);
     717                 :          12 :           update_stmt (mult_stmt);
     718                 :          12 :           if (dump_file)
     719                 :          10 :             print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
     720                 :             :       }
     721                 :             :     }
     722                 :             : 
     723                 :          12 :   if (has_other_use)
     724                 :             :     {
     725                 :             :       /* Using the two temporaries tmp1, tmp2 from above
     726                 :             :          the original x is now:
     727                 :             :          x = tmp1 * tmp2.  */
     728                 :          10 :       gcc_assert (orig_sqrt_ssa_name);
     729                 :          10 :       gcc_assert (sqr_ssa_name);
     730                 :             : 
     731                 :          10 :       gimple *new_stmt
     732                 :          10 :         = gimple_build_assign (x, MULT_EXPR,
     733                 :             :                                orig_sqrt_ssa_name, sqr_ssa_name);
     734                 :          10 :       gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
     735                 :          10 :       update_stmt (stmt);
     736                 :             :     }
     737                 :           2 :   else if (delete_div)
     738                 :             :     {
     739                 :             :       /* Remove the original division.  */
     740                 :           2 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
     741                 :           2 :       gsi_remove (&gsi2, true);
     742                 :           2 :       release_defs (stmt);
     743                 :             :     }
     744                 :             :   else
     745                 :           0 :     release_ssa_name (x);
     746                 :             : }
     747                 :             : 
     748                 :             : /* Look for floating-point divisions among DEF's uses, and try to
     749                 :             :    replace them by multiplications with the reciprocal.  Add
     750                 :             :    as many statements computing the reciprocal as needed.
     751                 :             : 
     752                 :             :    DEF must be a GIMPLE register of a floating-point type.  */
     753                 :             : 
     754                 :             : static void
     755                 :      196249 : execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
     756                 :             : {
     757                 :      196249 :   use_operand_p use_p, square_use_p;
     758                 :      196249 :   imm_use_iterator use_iter, square_use_iter;
     759                 :      196249 :   tree square_def;
     760                 :      196249 :   struct occurrence *occ;
     761                 :      196249 :   int count = 0;
     762                 :      196249 :   int threshold;
     763                 :      196249 :   int square_recip_count = 0;
     764                 :      196249 :   int sqrt_recip_count = 0;
     765                 :             : 
     766                 :      196249 :   gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && TREE_CODE (def) == SSA_NAME);
     767                 :      196249 :   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
     768                 :             : 
     769                 :             :   /* If DEF is a square (x * x), count the number of divisions by x.
     770                 :             :      If there are more divisions by x than by (DEF * DEF), prefer to optimize
     771                 :             :      the reciprocal of x instead of DEF.  This improves cases like:
     772                 :             :        def = x * x
     773                 :             :        t0 = a / def
     774                 :             :        t1 = b / def
     775                 :             :        t2 = c / x
     776                 :             :      Reciprocal optimization of x results in 1 division rather than 2 or 3.  */
     777                 :      196249 :   gimple *def_stmt = SSA_NAME_DEF_STMT (def);
     778                 :             : 
     779                 :      196249 :   if (is_gimple_assign (def_stmt)
     780                 :      146436 :       && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
     781                 :       36023 :       && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
     782                 :      232192 :       && gimple_assign_rhs1 (def_stmt) == gimple_assign_rhs2 (def_stmt))
     783                 :             :     {
     784                 :         677 :       tree op0 = gimple_assign_rhs1 (def_stmt);
     785                 :             : 
     786                 :        2767 :       FOR_EACH_IMM_USE_FAST (use_p, use_iter, op0)
     787                 :             :         {
     788                 :        2090 :           gimple *use_stmt = USE_STMT (use_p);
     789                 :        2090 :           if (is_division_by (use_stmt, op0))
     790                 :          19 :             sqrt_recip_count++;
     791                 :             :         }
     792                 :             :     }
     793                 :             : 
     794                 :      515632 :   FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
     795                 :             :     {
     796                 :      319383 :       gimple *use_stmt = USE_STMT (use_p);
     797                 :      319383 :       if (is_division_by (use_stmt, def))
     798                 :             :         {
     799                 :         641 :           register_division_in (gimple_bb (use_stmt), 2);
     800                 :         641 :           count++;
     801                 :             :         }
     802                 :             : 
     803                 :      319383 :       if (is_square_of (use_stmt, def))
     804                 :             :         {
     805                 :        1362 :           square_def = gimple_assign_lhs (use_stmt);
     806                 :        2882 :           FOR_EACH_IMM_USE_FAST (square_use_p, square_use_iter, square_def)
     807                 :             :             {
     808                 :        1520 :               gimple *square_use_stmt = USE_STMT (square_use_p);
     809                 :        1520 :               if (is_division_by (square_use_stmt, square_def))
     810                 :             :                 {
     811                 :             :                   /* This is executed twice for each division by a square.  */
     812                 :          66 :                   register_division_in (gimple_bb (square_use_stmt), 1);
     813                 :          66 :                   square_recip_count++;
     814                 :             :                 }
     815                 :             :             }
     816                 :             :         }
     817                 :             :     }
     818                 :             : 
     819                 :             :   /* Square reciprocals were counted twice above.  */
     820                 :      196249 :   square_recip_count /= 2;
     821                 :             : 
     822                 :             :   /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x).  */
     823                 :      196249 :   if (sqrt_recip_count > square_recip_count)
     824                 :          19 :     goto out;
     825                 :             : 
     826                 :             :   /* Do the expensive part only if we can hope to optimize something.  */
     827                 :      196230 :   if (count + square_recip_count >= threshold && count >= 1)
     828                 :             :     {
     829                 :          27 :       gimple *use_stmt;
     830                 :          54 :       for (occ = occ_head; occ; occ = occ->next)
     831                 :             :         {
     832                 :          27 :           compute_merit (occ);
     833                 :          27 :           insert_reciprocals (def_gsi, occ, def, NULL, NULL,
     834                 :             :                               square_recip_count, threshold);
     835                 :             :         }
     836                 :             : 
     837                 :         163 :       FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
     838                 :             :         {
     839                 :         136 :           if (is_division_by (use_stmt, def))
     840                 :             :             {
     841                 :         357 :               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
     842                 :         119 :                 replace_reciprocal (use_p);
     843                 :             :             }
     844                 :          21 :           else if (square_recip_count > 0 && is_square_of (use_stmt, def))
     845                 :             :             {
     846                 :          20 :               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
     847                 :             :                 {
     848                 :             :                   /* Find all uses of the square that are divisions and
     849                 :             :                    * replace them by multiplications with the inverse.  */
     850                 :           8 :                   imm_use_iterator square_iterator;
     851                 :           8 :                   gimple *powmult_use_stmt = USE_STMT (use_p);
     852                 :           8 :                   tree powmult_def_name = gimple_assign_lhs (powmult_use_stmt);
     853                 :             : 
     854                 :          14 :                   FOR_EACH_IMM_USE_STMT (powmult_use_stmt,
     855                 :             :                                          square_iterator, powmult_def_name)
     856                 :          18 :                     FOR_EACH_IMM_USE_ON_STMT (square_use_p, square_iterator)
     857                 :             :                       {
     858                 :           6 :                         gimple *powmult_use_stmt = USE_STMT (square_use_p);
     859                 :           6 :                         if (is_division_by (powmult_use_stmt, powmult_def_name))
     860                 :           4 :                           replace_reciprocal_squares (square_use_p);
     861                 :           8 :                       }
     862                 :             :                 }
     863                 :             :             }
     864                 :          27 :         }
     865                 :             :     }
     866                 :             : 
     867                 :      196203 : out:
     868                 :      196864 :   for (occ = occ_head; occ; )
     869                 :         615 :     occ = free_bb (occ);
     870                 :             : 
     871                 :      196249 :   occ_head = NULL;
     872                 :      196249 : }
     873                 :             : 
     874                 :             : /* Return an internal function that implements the reciprocal of CALL,
     875                 :             :    or IFN_LAST if there is no such function that the target supports.  */
     876                 :             : 
     877                 :             : internal_fn
     878                 :         134 : internal_fn_reciprocal (gcall *call)
     879                 :             : {
     880                 :         134 :   internal_fn ifn;
     881                 :             : 
     882                 :         134 :   switch (gimple_call_combined_fn (call))
     883                 :             :     {
     884                 :         118 :     CASE_CFN_SQRT:
     885                 :         118 :     CASE_CFN_SQRT_FN:
     886                 :         118 :       ifn = IFN_RSQRT;
     887                 :         118 :       break;
     888                 :             : 
     889                 :             :     default:
     890                 :             :       return IFN_LAST;
     891                 :             :     }
     892                 :             : 
     893                 :         118 :   tree_pair types = direct_internal_fn_types (ifn, call);
     894                 :         118 :   if (!direct_internal_fn_supported_p (ifn, types, OPTIMIZE_FOR_SPEED))
     895                 :             :     return IFN_LAST;
     896                 :             : 
     897                 :             :   return ifn;
     898                 :             : }
     899                 :             : 
     900                 :             : /* Go through all the floating-point SSA_NAMEs, and call
     901                 :             :    execute_cse_reciprocals_1 on each of them.  */
     902                 :             : namespace {
     903                 :             : 
     904                 :             : const pass_data pass_data_cse_reciprocals =
     905                 :             : {
     906                 :             :   GIMPLE_PASS, /* type */
     907                 :             :   "recip", /* name */
     908                 :             :   OPTGROUP_NONE, /* optinfo_flags */
     909                 :             :   TV_TREE_RECIP, /* tv_id */
     910                 :             :   PROP_ssa, /* properties_required */
     911                 :             :   0, /* properties_provided */
     912                 :             :   0, /* properties_destroyed */
     913                 :             :   0, /* todo_flags_start */
     914                 :             :   TODO_update_ssa, /* todo_flags_finish */
     915                 :             : };
     916                 :             : 
     917                 :             : class pass_cse_reciprocals : public gimple_opt_pass
     918                 :             : {
     919                 :             : public:
     920                 :      282866 :   pass_cse_reciprocals (gcc::context *ctxt)
     921                 :      565732 :     : gimple_opt_pass (pass_data_cse_reciprocals, ctxt)
     922                 :             :   {}
     923                 :             : 
     924                 :             :   /* opt_pass methods: */
     925                 :     1000974 :   bool gate (function *) final override
     926                 :             :   {
     927                 :     1000974 :     return optimize && flag_reciprocal_math;
     928                 :             :   }
     929                 :             :   unsigned int execute (function *) final override;
     930                 :             : 
     931                 :             : }; // class pass_cse_reciprocals
     932                 :             : 
     933                 :             : unsigned int
     934                 :        8626 : pass_cse_reciprocals::execute (function *fun)
     935                 :             : {
     936                 :        8626 :   basic_block bb;
     937                 :        8626 :   tree arg;
     938                 :             : 
     939                 :        8626 :   occ_pool = new object_allocator<occurrence> ("dominators for recip");
     940                 :             : 
     941                 :        8626 :   memset (&reciprocal_stats, 0, sizeof (reciprocal_stats));
     942                 :        8626 :   calculate_dominance_info (CDI_DOMINATORS);
     943                 :        8626 :   calculate_dominance_info (CDI_POST_DOMINATORS);
     944                 :             : 
     945                 :        8626 :   if (flag_checking)
     946                 :       96127 :     FOR_EACH_BB_FN (bb, fun)
     947                 :       87501 :       gcc_assert (!bb->aux);
     948                 :             : 
     949                 :       21311 :   for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg))
     950                 :       20145 :     if (FLOAT_TYPE_P (TREE_TYPE (arg))
     951                 :       13768 :         && is_gimple_reg (arg))
     952                 :             :       {
     953                 :        6307 :         tree name = ssa_default_def (fun, arg);
     954                 :        6307 :         if (name)
     955                 :        5312 :           execute_cse_reciprocals_1 (NULL, name);
     956                 :             :       }
     957                 :             : 
     958                 :       96127 :   FOR_EACH_BB_FN (bb, fun)
     959                 :             :     {
     960                 :       87501 :       tree def;
     961                 :             : 
     962                 :      205605 :       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     963                 :      118104 :            gsi_next (&gsi))
     964                 :             :         {
     965                 :      118104 :           gphi *phi = gsi.phi ();
     966                 :      118104 :           def = PHI_RESULT (phi);
     967                 :      118104 :           if (! virtual_operand_p (def)
     968                 :      118104 :               && FLOAT_TYPE_P (TREE_TYPE (def)))
     969                 :       35316 :             execute_cse_reciprocals_1 (NULL, def);
     970                 :             :         }
     971                 :             : 
     972                 :     1326069 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
     973                 :     1238568 :            gsi_next (&gsi))
     974                 :             :         {
     975                 :     1238568 :           gimple *stmt = gsi_stmt (gsi);
     976                 :             : 
     977                 :     2477136 :           if (gimple_has_lhs (stmt)
     978                 :      765546 :               && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
     979                 :      724214 :               && FLOAT_TYPE_P (TREE_TYPE (def))
     980                 :      177474 :               && TREE_CODE (def) == SSA_NAME)
     981                 :             :             {
     982                 :      155621 :               execute_cse_reciprocals_1 (&gsi, def);
     983                 :      155621 :               stmt = gsi_stmt (gsi);
     984                 :      155621 :               if (flag_unsafe_math_optimizations
     985                 :      155592 :                   && is_gimple_assign (stmt)
     986                 :      146409 :                   && gimple_assign_lhs (stmt) == def
     987                 :      146407 :                   && !stmt_can_throw_internal (cfun, stmt)
     988                 :      301984 :                   && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
     989                 :         566 :                 optimize_recip_sqrt (&gsi, def);
     990                 :             :             }
     991                 :             :         }
     992                 :             : 
     993                 :       87501 :       if (optimize_bb_for_size_p (bb))
     994                 :        4786 :         continue;
     995                 :             : 
     996                 :             :       /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b).  */
     997                 :     1311230 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
     998                 :     1228515 :            gsi_next (&gsi))
     999                 :             :         {
    1000                 :     1228515 :           gimple *stmt = gsi_stmt (gsi);
    1001                 :             : 
    1002                 :     1228515 :           if (is_gimple_assign (stmt)
    1003                 :     1228515 :               && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
    1004                 :             :             {
    1005                 :         600 :               tree arg1 = gimple_assign_rhs2 (stmt);
    1006                 :         600 :               gimple *stmt1;
    1007                 :             : 
    1008                 :         600 :               if (TREE_CODE (arg1) != SSA_NAME)
    1009                 :           5 :                 continue;
    1010                 :             : 
    1011                 :         595 :               stmt1 = SSA_NAME_DEF_STMT (arg1);
    1012                 :             : 
    1013                 :         595 :               if (is_gimple_call (stmt1)
    1014                 :         595 :                   && gimple_call_lhs (stmt1))
    1015                 :             :                 {
    1016                 :         134 :                   bool fail;
    1017                 :         134 :                   imm_use_iterator ui;
    1018                 :         134 :                   use_operand_p use_p;
    1019                 :         134 :                   tree fndecl = NULL_TREE;
    1020                 :             : 
    1021                 :         134 :                   gcall *call = as_a <gcall *> (stmt1);
    1022                 :         134 :                   internal_fn ifn = internal_fn_reciprocal (call);
    1023                 :         134 :                   if (ifn == IFN_LAST)
    1024                 :             :                     {
    1025                 :          71 :                       fndecl = gimple_call_fndecl (call);
    1026                 :         142 :                       if (!fndecl
    1027                 :          71 :                           || !fndecl_built_in_p (fndecl, BUILT_IN_MD))
    1028                 :          73 :                         continue;
    1029                 :           0 :                       fndecl = targetm.builtin_reciprocal (fndecl);
    1030                 :           0 :                       if (!fndecl)
    1031                 :           0 :                         continue;
    1032                 :             :                     }
    1033                 :             : 
    1034                 :             :                   /* Check that all uses of the SSA name are divisions,
    1035                 :             :                      otherwise replacing the defining statement will do
    1036                 :             :                      the wrong thing.  */
    1037                 :          63 :                   fail = false;
    1038                 :         126 :                   FOR_EACH_IMM_USE_FAST (use_p, ui, arg1)
    1039                 :             :                     {
    1040                 :          65 :                       gimple *stmt2 = USE_STMT (use_p);
    1041                 :          65 :                       if (is_gimple_debug (stmt2))
    1042                 :           0 :                         continue;
    1043                 :          65 :                       if (!is_gimple_assign (stmt2)
    1044                 :          65 :                           || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
    1045                 :          63 :                           || gimple_assign_rhs1 (stmt2) == arg1
    1046                 :         128 :                           || gimple_assign_rhs2 (stmt2) != arg1)
    1047                 :             :                         {
    1048                 :             :                           fail = true;
    1049                 :             :                           break;
    1050                 :             :                         }
    1051                 :             :                     }
    1052                 :          63 :                   if (fail)
    1053                 :           2 :                     continue;
    1054                 :             : 
    1055                 :          61 :                   gimple_replace_ssa_lhs (call, arg1);
    1056                 :          61 :                   if (gimple_call_internal_p (call) != (ifn != IFN_LAST))
    1057                 :             :                     {
    1058                 :          44 :                       auto_vec<tree, 4> args;
    1059                 :          44 :                       for (unsigned int i = 0;
    1060                 :          88 :                            i < gimple_call_num_args (call); i++)
    1061                 :          44 :                         args.safe_push (gimple_call_arg (call, i));
    1062                 :          44 :                       gcall *stmt2;
    1063                 :          44 :                       if (ifn == IFN_LAST)
    1064                 :           0 :                         stmt2 = gimple_build_call_vec (fndecl, args);
    1065                 :             :                       else
    1066                 :          44 :                         stmt2 = gimple_build_call_internal_vec (ifn, args);
    1067                 :          44 :                       gimple_call_set_lhs (stmt2, arg1);
    1068                 :          44 :                       gimple_move_vops (stmt2, call);
    1069                 :          44 :                       gimple_call_set_nothrow (stmt2,
    1070                 :          44 :                                                gimple_call_nothrow_p (call));
    1071                 :          44 :                       gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    1072                 :          44 :                       gsi_replace (&gsi2, stmt2, true);
    1073                 :          44 :                     }
    1074                 :             :                   else
    1075                 :             :                     {
    1076                 :          17 :                       if (ifn == IFN_LAST)
    1077                 :           0 :                         gimple_call_set_fndecl (call, fndecl);
    1078                 :             :                       else
    1079                 :          17 :                         gimple_call_set_internal_fn (call, ifn);
    1080                 :          17 :                       update_stmt (call);
    1081                 :             :                     }
    1082                 :          61 :                   reciprocal_stats.rfuncs_inserted++;
    1083                 :             : 
    1084                 :         122 :                   FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
    1085                 :             :                     {
    1086                 :          61 :                       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    1087                 :          61 :                       gimple_assign_set_rhs_code (stmt, MULT_EXPR);
    1088                 :          61 :                       fold_stmt_inplace (&gsi);
    1089                 :          61 :                       update_stmt (stmt);
    1090                 :          61 :                     }
    1091                 :             :                 }
    1092                 :             :             }
    1093                 :             :         }
    1094                 :             :     }
    1095                 :             : 
    1096                 :        8626 :   statistics_counter_event (fun, "reciprocal divs inserted",
    1097                 :             :                             reciprocal_stats.rdivs_inserted);
    1098                 :        8626 :   statistics_counter_event (fun, "reciprocal functions inserted",
    1099                 :             :                             reciprocal_stats.rfuncs_inserted);
    1100                 :             : 
    1101                 :        8626 :   free_dominance_info (CDI_DOMINATORS);
    1102                 :        8626 :   free_dominance_info (CDI_POST_DOMINATORS);
    1103                 :       17252 :   delete occ_pool;
    1104                 :        8626 :   return 0;
    1105                 :             : }
    1106                 :             : 
    1107                 :             : } // anon namespace
    1108                 :             : 
    1109                 :             : gimple_opt_pass *
    1110                 :      282866 : make_pass_cse_reciprocals (gcc::context *ctxt)
    1111                 :             : {
    1112                 :      282866 :   return new pass_cse_reciprocals (ctxt);
    1113                 :             : }
    1114                 :             : 
    1115                 :             : /* If NAME is the result of a type conversion, look for other
    1116                 :             :    equivalent dominating or dominated conversions, and replace all
    1117                 :             :    uses with the earliest dominating name, removing the redundant
    1118                 :             :    conversions.  Return the prevailing name.  */
    1119                 :             : 
    1120                 :             : static tree
    1121                 :        1029 : execute_cse_conv_1 (tree name, bool *cfg_changed)
    1122                 :             : {
    1123                 :        1029 :   if (SSA_NAME_IS_DEFAULT_DEF (name)
    1124                 :        1029 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
    1125                 :             :     return name;
    1126                 :             : 
    1127                 :         938 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
    1128                 :             : 
    1129                 :         938 :   if (!gimple_assign_cast_p (def_stmt))
    1130                 :             :     return name;
    1131                 :             : 
    1132                 :         136 :   tree src = gimple_assign_rhs1 (def_stmt);
    1133                 :             : 
    1134                 :         136 :   if (TREE_CODE (src) != SSA_NAME)
    1135                 :             :     return name;
    1136                 :             : 
    1137                 :         136 :   imm_use_iterator use_iter;
    1138                 :         136 :   gimple *use_stmt;
    1139                 :             : 
    1140                 :             :   /* Find the earliest dominating def.    */
    1141                 :         521 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, src)
    1142                 :             :     {
    1143                 :         763 :       if (use_stmt == def_stmt
    1144                 :         385 :           || !gimple_assign_cast_p (use_stmt))
    1145                 :         763 :         continue;
    1146                 :             : 
    1147                 :           7 :       tree lhs = gimple_assign_lhs (use_stmt);
    1148                 :             : 
    1149                 :           7 :       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
    1150                 :          14 :           || (gimple_assign_rhs1 (use_stmt)
    1151                 :           7 :               != gimple_assign_rhs1 (def_stmt))
    1152                 :          14 :           || !types_compatible_p (TREE_TYPE (name), TREE_TYPE (lhs)))
    1153                 :           0 :         continue;
    1154                 :             : 
    1155                 :           7 :       bool use_dominates;
    1156                 :           7 :       if (gimple_bb (def_stmt) == gimple_bb (use_stmt))
    1157                 :             :         {
    1158                 :           0 :           gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    1159                 :           0 :           while (!gsi_end_p (gsi) && gsi_stmt (gsi) != def_stmt)
    1160                 :           0 :             gsi_next (&gsi);
    1161                 :           0 :           use_dominates = !gsi_end_p (gsi);
    1162                 :             :         }
    1163                 :           7 :       else if (dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt),
    1164                 :           7 :                                gimple_bb (def_stmt)))
    1165                 :             :         use_dominates = false;
    1166                 :           7 :       else if (dominated_by_p (CDI_DOMINATORS, gimple_bb (def_stmt),
    1167                 :           7 :                                gimple_bb (use_stmt)))
    1168                 :             :         use_dominates = true;
    1169                 :             :       else
    1170                 :           4 :         continue;
    1171                 :             : 
    1172                 :           0 :       if (use_dominates)
    1173                 :             :         {
    1174                 :             :           std::swap (name, lhs);
    1175                 :             :           std::swap (def_stmt, use_stmt);
    1176                 :             :         }
    1177                 :         136 :     }
    1178                 :             : 
    1179                 :             :   /* Now go through all uses of SRC again, replacing the equivalent
    1180                 :             :      dominated conversions.  We may replace defs that were not
    1181                 :             :      dominated by the then-prevailing defs when we first visited
    1182                 :             :      them.  */
    1183                 :         521 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, src)
    1184                 :             :     {
    1185                 :         763 :       if (use_stmt == def_stmt
    1186                 :         385 :           || !gimple_assign_cast_p (use_stmt))
    1187                 :         378 :         continue;
    1188                 :             : 
    1189                 :           7 :       tree lhs = gimple_assign_lhs (use_stmt);
    1190                 :             : 
    1191                 :           7 :       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
    1192                 :          14 :           || (gimple_assign_rhs1 (use_stmt)
    1193                 :           7 :               != gimple_assign_rhs1 (def_stmt))
    1194                 :          14 :           || !types_compatible_p (TREE_TYPE (name), TREE_TYPE (lhs)))
    1195                 :           0 :         continue;
    1196                 :             : 
    1197                 :           7 :       basic_block use_bb = gimple_bb (use_stmt);
    1198                 :           7 :       if (gimple_bb (def_stmt) == use_bb
    1199                 :           7 :           || dominated_by_p (CDI_DOMINATORS, use_bb, gimple_bb (def_stmt)))
    1200                 :             :         {
    1201                 :           3 :           sincos_stats.conv_removed++;
    1202                 :             : 
    1203                 :           3 :           gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    1204                 :           3 :           replace_uses_by (lhs, name);
    1205                 :           3 :           if (gsi_remove (&gsi, true)
    1206                 :           3 :               && gimple_purge_dead_eh_edges (use_bb))
    1207                 :           3 :             *cfg_changed = true;
    1208                 :           3 :           release_defs (use_stmt);
    1209                 :             :         }
    1210                 :         136 :     }
    1211                 :             : 
    1212                 :         136 :   return name;
    1213                 :             : }
    1214                 :             : 
    1215                 :             : /* Records an occurrence at statement USE_STMT in the vector of trees
    1216                 :             :    STMTS if it is dominated by *TOP_BB or dominates it or this basic block
    1217                 :             :    is not yet initialized.  Returns true if the occurrence was pushed on
    1218                 :             :    the vector.  Adjusts *TOP_BB to be the basic block dominating all
    1219                 :             :    statements in the vector.  */
    1220                 :             : 
    1221                 :             : static bool
    1222                 :        1244 : maybe_record_sincos (vec<gimple *> *stmts,
    1223                 :             :                      basic_block *top_bb, gimple *use_stmt)
    1224                 :             : {
    1225                 :        1244 :   basic_block use_bb = gimple_bb (use_stmt);
    1226                 :        1244 :   if (*top_bb
    1227                 :        1244 :       && (*top_bb == use_bb
    1228                 :          66 :           || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
    1229                 :         156 :     stmts->safe_push (use_stmt);
    1230                 :        1088 :   else if (!*top_bb
    1231                 :        1088 :            || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
    1232                 :             :     {
    1233                 :        1068 :       stmts->safe_push (use_stmt);
    1234                 :        1068 :       *top_bb = use_bb;
    1235                 :             :     }
    1236                 :             :   else
    1237                 :             :     return false;
    1238                 :             : 
    1239                 :             :   return true;
    1240                 :             : }
    1241                 :             : 
    1242                 :             : /* Look for sin, cos and cexpi calls with the same argument NAME and
    1243                 :             :    create a single call to cexpi CSEing the result in this case.
    1244                 :             :    We first walk over all immediate uses of the argument collecting
    1245                 :             :    statements that we can CSE in a vector and in a second pass replace
    1246                 :             :    the statement rhs with a REALPART or IMAGPART expression on the
    1247                 :             :    result of the cexpi call we insert before the use statement that
    1248                 :             :    dominates all other candidates.  */
    1249                 :             : 
    1250                 :             : static bool
    1251                 :        1029 : execute_cse_sincos_1 (tree name)
    1252                 :             : {
    1253                 :        1029 :   gimple_stmt_iterator gsi;
    1254                 :        1029 :   imm_use_iterator use_iter;
    1255                 :        1029 :   tree fndecl, res, type = NULL_TREE;
    1256                 :        1029 :   gimple *def_stmt, *use_stmt, *stmt;
    1257                 :        1029 :   int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
    1258                 :        1029 :   auto_vec<gimple *> stmts;
    1259                 :        1029 :   basic_block top_bb = NULL;
    1260                 :        1029 :   int i;
    1261                 :        1029 :   bool cfg_changed = false;
    1262                 :             : 
    1263                 :        1029 :   name = execute_cse_conv_1 (name, &cfg_changed);
    1264                 :             : 
    1265                 :        3970 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
    1266                 :             :     {
    1267                 :        2941 :       if (gimple_code (use_stmt) != GIMPLE_CALL
    1268                 :        2941 :           || !gimple_call_lhs (use_stmt))
    1269                 :        1668 :         continue;
    1270                 :             : 
    1271                 :        1273 :       switch (gimple_call_combined_fn (use_stmt))
    1272                 :             :         {
    1273                 :         458 :         CASE_CFN_COS:
    1274                 :         458 :           seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1275                 :         458 :           break;
    1276                 :             : 
    1277                 :         781 :         CASE_CFN_SIN:
    1278                 :         781 :           seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1279                 :         781 :           break;
    1280                 :             : 
    1281                 :           5 :         CASE_CFN_CEXPI:
    1282                 :           5 :           seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1283                 :           5 :           break;
    1284                 :             : 
    1285                 :          29 :         default:;
    1286                 :          29 :           continue;
    1287                 :             :         }
    1288                 :             : 
    1289                 :        1244 :       tree t = mathfn_built_in_type (gimple_call_combined_fn (use_stmt));
    1290                 :        1244 :       if (!type)
    1291                 :             :         {
    1292                 :        1029 :           type = t;
    1293                 :        1029 :           t = TREE_TYPE (name);
    1294                 :             :         }
    1295                 :             :       /* This checks that NAME has the right type in the first round,
    1296                 :             :          and, in subsequent rounds, that the built_in type is the same
    1297                 :             :          type, or a compatible type.  */
    1298                 :        1244 :       if (type != t && !types_compatible_p (type, t))
    1299                 :           0 :         return false;
    1300                 :        1029 :     }
    1301                 :        1029 :   if (seen_cos + seen_sin + seen_cexpi <= 1)
    1302                 :             :     return false;
    1303                 :             : 
    1304                 :             :   /* Simply insert cexpi at the beginning of top_bb but not earlier than
    1305                 :             :      the name def statement.  */
    1306                 :         195 :   fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
    1307                 :         195 :   if (!fndecl)
    1308                 :             :     return false;
    1309                 :         151 :   stmt = gimple_build_call (fndecl, 1, name);
    1310                 :         151 :   res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), stmt, "sincostmp");
    1311                 :         151 :   gimple_call_set_lhs (stmt, res);
    1312                 :             : 
    1313                 :         151 :   def_stmt = SSA_NAME_DEF_STMT (name);
    1314                 :         151 :   if (!SSA_NAME_IS_DEFAULT_DEF (name)
    1315                 :         126 :       && gimple_code (def_stmt) != GIMPLE_PHI
    1316                 :         269 :       && gimple_bb (def_stmt) == top_bb)
    1317                 :             :     {
    1318                 :         118 :       gsi = gsi_for_stmt (def_stmt);
    1319                 :         118 :       gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
    1320                 :             :     }
    1321                 :             :   else
    1322                 :             :     {
    1323                 :          33 :       gsi = gsi_after_labels (top_bb);
    1324                 :          33 :       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    1325                 :             :     }
    1326                 :         151 :   sincos_stats.inserted++;
    1327                 :             : 
    1328                 :             :   /* And adjust the recorded old call sites.  */
    1329                 :         453 :   for (i = 0; stmts.iterate (i, &use_stmt); ++i)
    1330                 :             :     {
    1331                 :         302 :       tree rhs = NULL;
    1332                 :             : 
    1333                 :         302 :       switch (gimple_call_combined_fn (use_stmt))
    1334                 :             :         {
    1335                 :         151 :         CASE_CFN_COS:
    1336                 :         151 :           rhs = fold_build1 (REALPART_EXPR, type, res);
    1337                 :         151 :           break;
    1338                 :             : 
    1339                 :         151 :         CASE_CFN_SIN:
    1340                 :         151 :           rhs = fold_build1 (IMAGPART_EXPR, type, res);
    1341                 :         151 :           break;
    1342                 :             : 
    1343                 :             :         CASE_CFN_CEXPI:
    1344                 :             :           rhs = res;
    1345                 :             :           break;
    1346                 :             : 
    1347                 :           0 :         default:;
    1348                 :           0 :           gcc_unreachable ();
    1349                 :             :         }
    1350                 :             : 
    1351                 :             :         /* Replace call with a copy.  */
    1352                 :         302 :         stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs);
    1353                 :             : 
    1354                 :         302 :         gsi = gsi_for_stmt (use_stmt);
    1355                 :         302 :         gsi_replace (&gsi, stmt, true);
    1356                 :         302 :         if (gimple_purge_dead_eh_edges (gimple_bb (stmt)))
    1357                 :           0 :           cfg_changed = true;
    1358                 :             :     }
    1359                 :             : 
    1360                 :         151 :   return cfg_changed;
    1361                 :        1029 : }
    1362                 :             : 
    1363                 :             : /* To evaluate powi(x,n), the floating point value x raised to the
    1364                 :             :    constant integer exponent n, we use a hybrid algorithm that
    1365                 :             :    combines the "window method" with look-up tables.  For an
    1366                 :             :    introduction to exponentiation algorithms and "addition chains",
    1367                 :             :    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
    1368                 :             :    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
    1369                 :             :    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
    1370                 :             :    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
    1371                 :             : 
    1372                 :             : /* Provide a default value for POWI_MAX_MULTS, the maximum number of
    1373                 :             :    multiplications to inline before calling the system library's pow
    1374                 :             :    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
    1375                 :             :    so this default never requires calling pow, powf or powl.  */
    1376                 :             : 
    1377                 :             : #ifndef POWI_MAX_MULTS
    1378                 :             : #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
    1379                 :             : #endif
    1380                 :             : 
    1381                 :             : /* The size of the "optimal power tree" lookup table.  All
    1382                 :             :    exponents less than this value are simply looked up in the
    1383                 :             :    powi_table below.  This threshold is also used to size the
    1384                 :             :    cache of pseudo registers that hold intermediate results.  */
    1385                 :             : #define POWI_TABLE_SIZE 256
    1386                 :             : 
    1387                 :             : /* The size, in bits of the window, used in the "window method"
    1388                 :             :    exponentiation algorithm.  This is equivalent to a radix of
    1389                 :             :    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
    1390                 :             : #define POWI_WINDOW_SIZE 3
    1391                 :             : 
    1392                 :             : /* The following table is an efficient representation of an
    1393                 :             :    "optimal power tree".  For each value, i, the corresponding
    1394                 :             :    value, j, in the table states than an optimal evaluation
    1395                 :             :    sequence for calculating pow(x,i) can be found by evaluating
    1396                 :             :    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
    1397                 :             :    100 integers is given in Knuth's "Seminumerical algorithms".  */
    1398                 :             : 
    1399                 :             : static const unsigned char powi_table[POWI_TABLE_SIZE] =
    1400                 :             :   {
    1401                 :             :       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
    1402                 :             :       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
    1403                 :             :       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
    1404                 :             :      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
    1405                 :             :      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
    1406                 :             :      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
    1407                 :             :      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
    1408                 :             :      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
    1409                 :             :      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
    1410                 :             :      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
    1411                 :             :      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
    1412                 :             :      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
    1413                 :             :      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
    1414                 :             :      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
    1415                 :             :      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
    1416                 :             :      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
    1417                 :             :      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
    1418                 :             :      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
    1419                 :             :      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
    1420                 :             :      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
    1421                 :             :      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
    1422                 :             :      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
    1423                 :             :      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
    1424                 :             :      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
    1425                 :             :      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
    1426                 :             :     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
    1427                 :             :     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
    1428                 :             :     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
    1429                 :             :     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
    1430                 :             :     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
    1431                 :             :     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
    1432                 :             :     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
    1433                 :             :   };
    1434                 :             : 
    1435                 :             : 
    1436                 :             : /* Return the number of multiplications required to calculate
    1437                 :             :    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
    1438                 :             :    subroutine of powi_cost.  CACHE is an array indicating
    1439                 :             :    which exponents have already been calculated.  */
    1440                 :             : 
    1441                 :             : static int
    1442                 :        1122 : powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
    1443                 :             : {
    1444                 :             :   /* If we've already calculated this exponent, then this evaluation
    1445                 :             :      doesn't require any additional multiplications.  */
    1446                 :        1864 :   if (cache[n])
    1447                 :        1122 :     return 0;
    1448                 :             : 
    1449                 :         742 :   cache[n] = true;
    1450                 :         742 :   return powi_lookup_cost (n - powi_table[n], cache)
    1451                 :         742 :          + powi_lookup_cost (powi_table[n], cache) + 1;
    1452                 :             : }
    1453                 :             : 
    1454                 :             : /* Return the number of multiplications required to calculate
    1455                 :             :    powi(x,n) for an arbitrary x, given the exponent N.  This
    1456                 :             :    function needs to be kept in sync with powi_as_mults below.  */
    1457                 :             : 
    1458                 :             : static int
    1459                 :         385 : powi_cost (HOST_WIDE_INT n)
    1460                 :             : {
    1461                 :         385 :   bool cache[POWI_TABLE_SIZE];
    1462                 :         385 :   unsigned HOST_WIDE_INT digit;
    1463                 :         385 :   unsigned HOST_WIDE_INT val;
    1464                 :         385 :   int result;
    1465                 :             : 
    1466                 :         385 :   if (n == 0)
    1467                 :             :     return 0;
    1468                 :             : 
    1469                 :             :   /* Ignore the reciprocal when calculating the cost.  */
    1470                 :         380 :   val = absu_hwi (n);
    1471                 :             : 
    1472                 :             :   /* Initialize the exponent cache.  */
    1473                 :         380 :   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
    1474                 :         380 :   cache[1] = true;
    1475                 :             : 
    1476                 :         380 :   result = 0;
    1477                 :             : 
    1478                 :         380 :   while (val >= POWI_TABLE_SIZE)
    1479                 :             :     {
    1480                 :           0 :       if (val & 1)
    1481                 :             :         {
    1482                 :           0 :           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
    1483                 :           0 :           result += powi_lookup_cost (digit, cache)
    1484                 :           0 :                     + POWI_WINDOW_SIZE + 1;
    1485                 :           0 :           val >>= POWI_WINDOW_SIZE;
    1486                 :             :         }
    1487                 :             :       else
    1488                 :             :         {
    1489                 :           0 :           val >>= 1;
    1490                 :           0 :           result++;
    1491                 :             :         }
    1492                 :             :     }
    1493                 :             : 
    1494                 :         380 :   return result + powi_lookup_cost (val, cache);
    1495                 :             : }
    1496                 :             : 
    1497                 :             : /* Recursive subroutine of powi_as_mults.  This function takes the
    1498                 :             :    array, CACHE, of already calculated exponents and an exponent N and
    1499                 :             :    returns a tree that corresponds to CACHE[1]**N, with type TYPE.  */
    1500                 :             : 
    1501                 :             : static tree
    1502                 :        5954 : powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type,
    1503                 :             :                  unsigned HOST_WIDE_INT n, tree *cache)
    1504                 :             : {
    1505                 :        5954 :   tree op0, op1, ssa_target;
    1506                 :        5954 :   unsigned HOST_WIDE_INT digit;
    1507                 :        5954 :   gassign *mult_stmt;
    1508                 :             : 
    1509                 :        5954 :   if (n < POWI_TABLE_SIZE && cache[n])
    1510                 :             :     return cache[n];
    1511                 :             : 
    1512                 :        2113 :   ssa_target = make_temp_ssa_name (type, NULL, "powmult");
    1513                 :             : 
    1514                 :        2113 :   if (n < POWI_TABLE_SIZE)
    1515                 :             :     {
    1516                 :        2110 :       cache[n] = ssa_target;
    1517                 :        2110 :       op0 = powi_as_mults_1 (gsi, loc, type, n - powi_table[n], cache);
    1518                 :        2110 :       op1 = powi_as_mults_1 (gsi, loc, type, powi_table[n], cache);
    1519                 :             :     }
    1520                 :           3 :   else if (n & 1)
    1521                 :             :     {
    1522                 :           1 :       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
    1523                 :           1 :       op0 = powi_as_mults_1 (gsi, loc, type, n - digit, cache);
    1524                 :           1 :       op1 = powi_as_mults_1 (gsi, loc, type, digit, cache);
    1525                 :             :     }
    1526                 :             :   else
    1527                 :             :     {
    1528                 :           2 :       op0 = powi_as_mults_1 (gsi, loc, type, n >> 1, cache);
    1529                 :           2 :       op1 = op0;
    1530                 :             :     }
    1531                 :             : 
    1532                 :        2113 :   mult_stmt = gimple_build_assign (ssa_target, MULT_EXPR, op0, op1);
    1533                 :        2113 :   gimple_set_location (mult_stmt, loc);
    1534                 :        2113 :   gsi_insert_before (gsi, mult_stmt, GSI_SAME_STMT);
    1535                 :             : 
    1536                 :        2113 :   return ssa_target;
    1537                 :             : }
    1538                 :             : 
    1539                 :             : /* Convert ARG0**N to a tree of multiplications of ARG0 with itself.
    1540                 :             :    This function needs to be kept in sync with powi_cost above.  */
    1541                 :             : 
    1542                 :             : tree
    1543                 :        1730 : powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
    1544                 :             :                tree arg0, HOST_WIDE_INT n)
    1545                 :             : {
    1546                 :        1730 :   tree cache[POWI_TABLE_SIZE], result, type = TREE_TYPE (arg0);
    1547                 :        1730 :   gassign *div_stmt;
    1548                 :        1730 :   tree target;
    1549                 :             : 
    1550                 :        1730 :   if (n == 0)
    1551                 :           0 :     return build_one_cst (type);
    1552                 :             : 
    1553                 :        1730 :   memset (cache, 0, sizeof (cache));
    1554                 :        1730 :   cache[1] = arg0;
    1555                 :             : 
    1556                 :        1730 :   result = powi_as_mults_1 (gsi, loc, type, absu_hwi (n), cache);
    1557                 :        1730 :   if (n >= 0)
    1558                 :             :     return result;
    1559                 :             : 
    1560                 :             :   /* If the original exponent was negative, reciprocate the result.  */
    1561                 :           8 :   target = make_temp_ssa_name (type, NULL, "powmult");
    1562                 :           8 :   div_stmt = gimple_build_assign (target, RDIV_EXPR,
    1563                 :             :                                   build_real (type, dconst1), result);
    1564                 :           8 :   gimple_set_location (div_stmt, loc);
    1565                 :           8 :   gsi_insert_before (gsi, div_stmt, GSI_SAME_STMT);
    1566                 :             : 
    1567                 :           8 :   return target;
    1568                 :             : }
    1569                 :             : 
    1570                 :             : /* ARG0 and N are the two arguments to a powi builtin in GSI with
    1571                 :             :    location info LOC.  If the arguments are appropriate, create an
    1572                 :             :    equivalent sequence of statements prior to GSI using an optimal
    1573                 :             :    number of multiplications, and return an expession holding the
    1574                 :             :    result.  */
    1575                 :             : 
    1576                 :             : static tree
    1577                 :         664 : gimple_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc,
    1578                 :             :                             tree arg0, HOST_WIDE_INT n)
    1579                 :             : {
    1580                 :         664 :   if ((n >= -1 && n <= 2)
    1581                 :         664 :       || (optimize_function_for_speed_p (cfun)
    1582                 :         351 :           && powi_cost (n) <= POWI_MAX_MULTS))
    1583                 :         656 :     return powi_as_mults (gsi, loc, arg0, n);
    1584                 :             : 
    1585                 :             :   return NULL_TREE;
    1586                 :             : }
    1587                 :             : 
    1588                 :             : /* Build a gimple call statement that calls FN with argument ARG.
    1589                 :             :    Set the lhs of the call statement to a fresh SSA name.  Insert the
    1590                 :             :    statement prior to GSI's current position, and return the fresh
    1591                 :             :    SSA name.  */
    1592                 :             : 
    1593                 :             : static tree
    1594                 :          45 : build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc,
    1595                 :             :                        tree fn, tree arg)
    1596                 :             : {
    1597                 :          45 :   gcall *call_stmt;
    1598                 :          45 :   tree ssa_target;
    1599                 :             : 
    1600                 :          45 :   call_stmt = gimple_build_call (fn, 1, arg);
    1601                 :          45 :   ssa_target = make_temp_ssa_name (TREE_TYPE (arg), NULL, "powroot");
    1602                 :          45 :   gimple_set_lhs (call_stmt, ssa_target);
    1603                 :          45 :   gimple_set_location (call_stmt, loc);
    1604                 :          45 :   gsi_insert_before (gsi, call_stmt, GSI_SAME_STMT);
    1605                 :             : 
    1606                 :          45 :   return ssa_target;
    1607                 :             : }
    1608                 :             : 
    1609                 :             : /* Build a gimple binary operation with the given CODE and arguments
    1610                 :             :    ARG0, ARG1, assigning the result to a new SSA name for variable
    1611                 :             :    TARGET.  Insert the statement prior to GSI's current position, and
    1612                 :             :    return the fresh SSA name.*/
    1613                 :             : 
    1614                 :             : static tree
    1615                 :         903 : build_and_insert_binop (gimple_stmt_iterator *gsi, location_t loc,
    1616                 :             :                         const char *name, enum tree_code code,
    1617                 :             :                         tree arg0, tree arg1)
    1618                 :             : {
    1619                 :         903 :   tree result = make_temp_ssa_name (TREE_TYPE (arg0), NULL, name);
    1620                 :         903 :   gassign *stmt = gimple_build_assign (result, code, arg0, arg1);
    1621                 :         903 :   gimple_set_location (stmt, loc);
    1622                 :         903 :   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    1623                 :         903 :   return result;
    1624                 :             : }
    1625                 :             : 
    1626                 :             : /* Build a gimple assignment to cast VAL to TYPE.  Insert the statement
    1627                 :             :    prior to GSI's current position, and return the fresh SSA name.  */
    1628                 :             : 
    1629                 :             : static tree
    1630                 :       16994 : build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
    1631                 :             :                        tree type, tree val)
    1632                 :             : {
    1633                 :       16994 :   tree result = make_ssa_name (type);
    1634                 :       16994 :   gassign *stmt = gimple_build_assign (result, NOP_EXPR, val);
    1635                 :       16994 :   gimple_set_location (stmt, loc);
    1636                 :       16994 :   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    1637                 :       16994 :   return result;
    1638                 :             : }
    1639                 :             : 
    1640                 :             : struct pow_synth_sqrt_info
    1641                 :             : {
    1642                 :             :   bool *factors;
    1643                 :             :   unsigned int deepest;
    1644                 :             :   unsigned int num_mults;
    1645                 :             : };
    1646                 :             : 
    1647                 :             : /* Return true iff the real value C can be represented as a
    1648                 :             :    sum of powers of 0.5 up to N.  That is:
    1649                 :             :    C == SUM<i from 1..N> (a[i]*(0.5**i)) where a[i] is either 0 or 1.
    1650                 :             :    Record in INFO the various parameters of the synthesis algorithm such
    1651                 :             :    as the factors a[i], the maximum 0.5 power and the number of
    1652                 :             :    multiplications that will be required.  */
    1653                 :             : 
    1654                 :             : bool
    1655                 :          34 : representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
    1656                 :             :                                  struct pow_synth_sqrt_info *info)
    1657                 :             : {
    1658                 :          34 :   REAL_VALUE_TYPE factor = dconsthalf;
    1659                 :          34 :   REAL_VALUE_TYPE remainder = c;
    1660                 :             : 
    1661                 :          34 :   info->deepest = 0;
    1662                 :          34 :   info->num_mults = 0;
    1663                 :          34 :   memset (info->factors, 0, n * sizeof (bool));
    1664                 :             : 
    1665                 :          98 :   for (unsigned i = 0; i < n; i++)
    1666                 :             :     {
    1667                 :          91 :       REAL_VALUE_TYPE res;
    1668                 :             : 
    1669                 :             :       /* If something inexact happened bail out now.  */
    1670                 :          91 :       if (real_arithmetic (&res, MINUS_EXPR, &remainder, &factor))
    1671                 :          27 :         return false;
    1672                 :             : 
    1673                 :             :       /* We have hit zero.  The number is representable as a sum
    1674                 :             :          of powers of 0.5.  */
    1675                 :          91 :       if (real_equal (&res, &dconst0))
    1676                 :             :         {
    1677                 :          27 :           info->factors[i] = true;
    1678                 :          27 :           info->deepest = i + 1;
    1679                 :          27 :           return true;
    1680                 :             :         }
    1681                 :          64 :       else if (!REAL_VALUE_NEGATIVE (res))
    1682                 :             :         {
    1683                 :          29 :           remainder = res;
    1684                 :          29 :           info->factors[i] = true;
    1685                 :          29 :           info->num_mults++;
    1686                 :             :         }
    1687                 :             :       else
    1688                 :          35 :         info->factors[i] = false;
    1689                 :             : 
    1690                 :          64 :       real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
    1691                 :             :     }
    1692                 :             :   return false;
    1693                 :             : }
    1694                 :             : 
    1695                 :             : /* Return the tree corresponding to FN being applied
    1696                 :             :    to ARG N times at GSI and LOC.
    1697                 :             :    Look up previous results from CACHE if need be.
    1698                 :             :    cache[0] should contain just plain ARG i.e. FN applied to ARG 0 times.  */
    1699                 :             : 
    1700                 :             : static tree
    1701                 :          65 : get_fn_chain (tree arg, unsigned int n, gimple_stmt_iterator *gsi,
    1702                 :             :               tree fn, location_t loc, tree *cache)
    1703                 :             : {
    1704                 :          65 :   tree res = cache[n];
    1705                 :          65 :   if (!res)
    1706                 :             :     {
    1707                 :          41 :       tree prev = get_fn_chain (arg, n - 1, gsi, fn, loc, cache);
    1708                 :          41 :       res = build_and_insert_call (gsi, loc, fn, prev);
    1709                 :          41 :       cache[n] = res;
    1710                 :             :     }
    1711                 :             : 
    1712                 :          65 :   return res;
    1713                 :             : }
    1714                 :             : 
    1715                 :             : /* Print to STREAM the repeated application of function FNAME to ARG
    1716                 :             :    N times.  So, for FNAME = "foo", ARG = "x", N = 2 it would print:
    1717                 :             :    "foo (foo (x))".  */
    1718                 :             : 
    1719                 :             : static void
    1720                 :          36 : print_nested_fn (FILE* stream, const char *fname, const char* arg,
    1721                 :             :                  unsigned int n)
    1722                 :             : {
    1723                 :          36 :   if (n == 0)
    1724                 :          10 :     fprintf (stream, "%s", arg);
    1725                 :             :   else
    1726                 :             :     {
    1727                 :          26 :       fprintf (stream, "%s (", fname);
    1728                 :          26 :       print_nested_fn (stream, fname, arg, n - 1);
    1729                 :          26 :       fprintf (stream, ")");
    1730                 :             :     }
    1731                 :          36 : }
    1732                 :             : 
    1733                 :             : /* Print to STREAM the fractional sequence of sqrt chains
    1734                 :             :    applied to ARG, described by INFO.  Used for the dump file.  */
    1735                 :             : 
    1736                 :             : static void
    1737                 :           7 : dump_fractional_sqrt_sequence (FILE *stream, const char *arg,
    1738                 :             :                                 struct pow_synth_sqrt_info *info)
    1739                 :             : {
    1740                 :          29 :   for (unsigned int i = 0; i < info->deepest; i++)
    1741                 :             :     {
    1742                 :          22 :       bool is_set = info->factors[i];
    1743                 :          22 :       if (is_set)
    1744                 :             :         {
    1745                 :          10 :           print_nested_fn (stream, "sqrt", arg, i + 1);
    1746                 :          10 :           if (i != info->deepest - 1)
    1747                 :           3 :             fprintf (stream, " * ");
    1748                 :             :         }
    1749                 :             :     }
    1750                 :           7 : }
    1751                 :             : 
    1752                 :             : /* Print to STREAM a representation of raising ARG to an integer
    1753                 :             :    power N.  Used for the dump file.  */
    1754                 :             : 
    1755                 :             : static void
    1756                 :           7 : dump_integer_part (FILE *stream, const char* arg, HOST_WIDE_INT n)
    1757                 :             : {
    1758                 :           7 :   if (n > 1)
    1759                 :           3 :     fprintf (stream, "powi (%s, " HOST_WIDE_INT_PRINT_DEC ")", arg, n);
    1760                 :           4 :   else if (n == 1)
    1761                 :           3 :     fprintf (stream, "%s", arg);
    1762                 :           7 : }
    1763                 :             : 
    1764                 :             : /* Attempt to synthesize a POW[F] (ARG0, ARG1) call using chains of
    1765                 :             :    square roots.  Place at GSI and LOC.  Limit the maximum depth
    1766                 :             :    of the sqrt chains to MAX_DEPTH.  Return the tree holding the
    1767                 :             :    result of the expanded sequence or NULL_TREE if the expansion failed.
    1768                 :             : 
    1769                 :             :    This routine assumes that ARG1 is a real number with a fractional part
    1770                 :             :    (the integer exponent case will have been handled earlier in
    1771                 :             :    gimple_expand_builtin_pow).
    1772                 :             : 
    1773                 :             :    For ARG1 > 0.0:
    1774                 :             :    * For ARG1 composed of a whole part WHOLE_PART and a fractional part
    1775                 :             :      FRAC_PART i.e. WHOLE_PART == floor (ARG1) and
    1776                 :             :                     FRAC_PART == ARG1 - WHOLE_PART:
    1777                 :             :      Produce POWI (ARG0, WHOLE_PART) * POW (ARG0, FRAC_PART) where
    1778                 :             :      POW (ARG0, FRAC_PART) is expanded as a product of square root chains
    1779                 :             :      if it can be expressed as such, that is if FRAC_PART satisfies:
    1780                 :             :      FRAC_PART == <SUM from i = 1 until MAX_DEPTH> (a[i] * (0.5**i))
    1781                 :             :      where integer a[i] is either 0 or 1.
    1782                 :             : 
    1783                 :             :      Example:
    1784                 :             :      POW (x, 3.625) == POWI (x, 3) * POW (x, 0.625)
    1785                 :             :        --> POWI (x, 3) * SQRT (x) * SQRT (SQRT (SQRT (x)))
    1786                 :             : 
    1787                 :             :    For ARG1 < 0.0 there are two approaches:
    1788                 :             :    * (A) Expand to 1.0 / POW (ARG0, -ARG1) where POW (ARG0, -ARG1)
    1789                 :             :          is calculated as above.
    1790                 :             : 
    1791                 :             :      Example:
    1792                 :             :      POW (x, -5.625) == 1.0 / POW (x, 5.625)
    1793                 :             :        -->  1.0 / (POWI (x, 5) * SQRT (x) * SQRT (SQRT (SQRT (x))))
    1794                 :             : 
    1795                 :             :    * (B) : WHOLE_PART := - ceil (abs (ARG1))
    1796                 :             :            FRAC_PART  := ARG1 - WHOLE_PART
    1797                 :             :      and expand to POW (x, FRAC_PART) / POWI (x, WHOLE_PART).
    1798                 :             :      Example:
    1799                 :             :      POW (x, -5.875) == POW (x, 0.125) / POWI (X, 6)
    1800                 :             :        --> SQRT (SQRT (SQRT (x))) / (POWI (x, 6))
    1801                 :             : 
    1802                 :             :    For ARG1 < 0.0 we choose between (A) and (B) depending on
    1803                 :             :    how many multiplications we'd have to do.
    1804                 :             :    So, for the example in (B): POW (x, -5.875), if we were to
    1805                 :             :    follow algorithm (A) we would produce:
    1806                 :             :    1.0 / POWI (X, 5) * SQRT (X) * SQRT (SQRT (X)) * SQRT (SQRT (SQRT (X)))
    1807                 :             :    which contains more multiplications than approach (B).
    1808                 :             : 
    1809                 :             :    Hopefully, this approach will eliminate potentially expensive POW library
    1810                 :             :    calls when unsafe floating point math is enabled and allow the compiler to
    1811                 :             :    further optimise the multiplies, square roots and divides produced by this
    1812                 :             :    function.  */
    1813                 :             : 
    1814                 :             : static tree
    1815                 :          26 : expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
    1816                 :             :                      tree arg0, tree arg1, HOST_WIDE_INT max_depth)
    1817                 :             : {
    1818                 :          26 :   tree type = TREE_TYPE (arg0);
    1819                 :          26 :   machine_mode mode = TYPE_MODE (type);
    1820                 :          26 :   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
    1821                 :          26 :   bool one_over = true;
    1822                 :             : 
    1823                 :          26 :   if (!sqrtfn)
    1824                 :             :     return NULL_TREE;
    1825                 :             : 
    1826                 :          26 :   if (TREE_CODE (arg1) != REAL_CST)
    1827                 :             :     return NULL_TREE;
    1828                 :             : 
    1829                 :          26 :   REAL_VALUE_TYPE exp_init = TREE_REAL_CST (arg1);
    1830                 :             : 
    1831                 :          26 :   gcc_assert (max_depth > 0);
    1832                 :          26 :   tree *cache = XALLOCAVEC (tree, max_depth + 1);
    1833                 :             : 
    1834                 :          26 :   struct pow_synth_sqrt_info synth_info;
    1835                 :          26 :   synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
    1836                 :          26 :   synth_info.deepest = 0;
    1837                 :          26 :   synth_info.num_mults = 0;
    1838                 :             : 
    1839                 :          26 :   bool neg_exp = REAL_VALUE_NEGATIVE (exp_init);
    1840                 :          26 :   REAL_VALUE_TYPE exp = real_value_abs (&exp_init);
    1841                 :             : 
    1842                 :             :   /* The whole and fractional parts of exp.  */
    1843                 :          26 :   REAL_VALUE_TYPE whole_part;
    1844                 :          26 :   REAL_VALUE_TYPE frac_part;
    1845                 :             : 
    1846                 :          26 :   real_floor (&whole_part, mode, &exp);
    1847                 :          26 :   real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
    1848                 :             : 
    1849                 :             : 
    1850                 :          26 :   REAL_VALUE_TYPE ceil_whole = dconst0;
    1851                 :          26 :   REAL_VALUE_TYPE ceil_fract = dconst0;
    1852                 :             : 
    1853                 :          26 :   if (neg_exp)
    1854                 :             :     {
    1855                 :          10 :       real_ceil (&ceil_whole, mode, &exp);
    1856                 :          10 :       real_arithmetic (&ceil_fract, MINUS_EXPR, &ceil_whole, &exp);
    1857                 :             :     }
    1858                 :             : 
    1859                 :          26 :   if (!representable_as_half_series_p (frac_part, max_depth, &synth_info))
    1860                 :             :     return NULL_TREE;
    1861                 :             : 
    1862                 :             :   /* Check whether it's more profitable to not use 1.0 / ...  */
    1863                 :          19 :   if (neg_exp)
    1864                 :             :     {
    1865                 :           8 :       struct pow_synth_sqrt_info alt_synth_info;
    1866                 :           8 :       alt_synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
    1867                 :           8 :       alt_synth_info.deepest = 0;
    1868                 :           8 :       alt_synth_info.num_mults = 0;
    1869                 :             : 
    1870                 :           8 :       if (representable_as_half_series_p (ceil_fract, max_depth,
    1871                 :             :                                            &alt_synth_info)
    1872                 :           8 :           && alt_synth_info.deepest <= synth_info.deepest
    1873                 :          16 :           && alt_synth_info.num_mults < synth_info.num_mults)
    1874                 :             :         {
    1875                 :           2 :           whole_part = ceil_whole;
    1876                 :           2 :           frac_part = ceil_fract;
    1877                 :           2 :           synth_info.deepest = alt_synth_info.deepest;
    1878                 :           2 :           synth_info.num_mults = alt_synth_info.num_mults;
    1879                 :           2 :           memcpy (synth_info.factors, alt_synth_info.factors,
    1880                 :             :                   (max_depth + 1) * sizeof (bool));
    1881                 :           2 :           one_over = false;
    1882                 :             :         }
    1883                 :             :     }
    1884                 :             : 
    1885                 :          19 :   HOST_WIDE_INT n = real_to_integer (&whole_part);
    1886                 :          19 :   REAL_VALUE_TYPE cint;
    1887                 :          19 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    1888                 :             : 
    1889                 :          19 :   if (!real_identical (&whole_part, &cint))
    1890                 :             :     return NULL_TREE;
    1891                 :             : 
    1892                 :          19 :   if (powi_cost (n) + synth_info.num_mults > POWI_MAX_MULTS)
    1893                 :             :     return NULL_TREE;
    1894                 :             : 
    1895                 :          19 :   memset (cache, 0, (max_depth + 1) * sizeof (tree));
    1896                 :             : 
    1897                 :          19 :   tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
    1898                 :             : 
    1899                 :             :   /* Calculate the integer part of the exponent.  */
    1900                 :          19 :   if (n > 1)
    1901                 :             :     {
    1902                 :           7 :       integer_res = gimple_expand_builtin_powi (gsi, loc, arg0, n);
    1903                 :           7 :       if (!integer_res)
    1904                 :             :         return NULL_TREE;
    1905                 :             :     }
    1906                 :             : 
    1907                 :          19 :   if (dump_file)
    1908                 :             :     {
    1909                 :           7 :       char string[64];
    1910                 :             : 
    1911                 :           7 :       real_to_decimal (string, &exp_init, sizeof (string), 0, 1);
    1912                 :           7 :       fprintf (dump_file, "synthesizing pow (x, %s) as:\n", string);
    1913                 :             : 
    1914                 :           7 :       if (neg_exp)
    1915                 :             :         {
    1916                 :           2 :           if (one_over)
    1917                 :             :             {
    1918                 :           1 :               fprintf (dump_file, "1.0 / (");
    1919                 :           1 :               dump_integer_part (dump_file, "x", n);
    1920                 :           1 :               if (n > 0)
    1921                 :           1 :                 fprintf (dump_file, " * ");
    1922                 :           1 :               dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1923                 :           1 :               fprintf (dump_file, ")");
    1924                 :             :             }
    1925                 :             :           else
    1926                 :             :             {
    1927                 :           1 :               dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1928                 :           1 :               fprintf (dump_file, " / (");
    1929                 :           1 :               dump_integer_part (dump_file, "x", n);
    1930                 :           1 :               fprintf (dump_file, ")");
    1931                 :             :             }
    1932                 :             :         }
    1933                 :             :       else
    1934                 :             :         {
    1935                 :           5 :           dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1936                 :           5 :           if (n > 0)
    1937                 :           4 :             fprintf (dump_file, " * ");
    1938                 :           5 :           dump_integer_part (dump_file, "x", n);
    1939                 :             :         }
    1940                 :             : 
    1941                 :           7 :       fprintf (dump_file, "\ndeepest sqrt chain: %d\n", synth_info.deepest);
    1942                 :             :     }
    1943                 :             : 
    1944                 :             : 
    1945                 :          19 :   tree fract_res = NULL_TREE;
    1946                 :          19 :   cache[0] = arg0;
    1947                 :             : 
    1948                 :             :   /* Calculate the fractional part of the exponent.  */
    1949                 :          60 :   for (unsigned i = 0; i < synth_info.deepest; i++)
    1950                 :             :     {
    1951                 :          41 :       if (synth_info.factors[i])
    1952                 :             :         {
    1953                 :          24 :           tree sqrt_chain = get_fn_chain (arg0, i + 1, gsi, sqrtfn, loc, cache);
    1954                 :             : 
    1955                 :          24 :           if (!fract_res)
    1956                 :             :               fract_res = sqrt_chain;
    1957                 :             : 
    1958                 :             :           else
    1959                 :           5 :             fract_res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1960                 :             :                                            fract_res, sqrt_chain);
    1961                 :             :         }
    1962                 :             :     }
    1963                 :             : 
    1964                 :          19 :   tree res = NULL_TREE;
    1965                 :             : 
    1966                 :          19 :   if (neg_exp)
    1967                 :             :     {
    1968                 :           8 :       if (one_over)
    1969                 :             :         {
    1970                 :           6 :           if (n > 0)
    1971                 :           4 :             res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1972                 :             :                                            fract_res, integer_res);
    1973                 :             :           else
    1974                 :             :             res = fract_res;
    1975                 :             : 
    1976                 :           6 :           res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
    1977                 :             :                                           build_real (type, dconst1), res);
    1978                 :             :         }
    1979                 :             :       else
    1980                 :             :         {
    1981                 :           2 :           res = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
    1982                 :             :                                          fract_res, integer_res);
    1983                 :             :         }
    1984                 :             :     }
    1985                 :             :   else
    1986                 :          11 :     res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1987                 :             :                                    fract_res, integer_res);
    1988                 :             :   return res;
    1989                 :             : }
    1990                 :             : 
    1991                 :             : /* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
    1992                 :             :    with location info LOC.  If possible, create an equivalent and
    1993                 :             :    less expensive sequence of statements prior to GSI, and return an
    1994                 :             :    expession holding the result.  */
    1995                 :             : 
    1996                 :             : static tree
    1997                 :         595 : gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
    1998                 :             :                            tree arg0, tree arg1)
    1999                 :             : {
    2000                 :         595 :   REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
    2001                 :         595 :   REAL_VALUE_TYPE c2, dconst3;
    2002                 :         595 :   HOST_WIDE_INT n;
    2003                 :         595 :   tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
    2004                 :         595 :   machine_mode mode;
    2005                 :         595 :   bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
    2006                 :         595 :   bool hw_sqrt_exists, c_is_int, c2_is_int;
    2007                 :             : 
    2008                 :         595 :   dconst1_4 = dconst1;
    2009                 :         595 :   SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
    2010                 :             : 
    2011                 :             :   /* If the exponent isn't a constant, there's nothing of interest
    2012                 :             :      to be done.  */
    2013                 :         595 :   if (TREE_CODE (arg1) != REAL_CST)
    2014                 :             :     return NULL_TREE;
    2015                 :             : 
    2016                 :             :   /* Don't perform the operation if flag_signaling_nans is on
    2017                 :             :      and the operand is a signaling NaN.  */
    2018                 :         356 :   if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
    2019                 :         356 :       && ((TREE_CODE (arg0) == REAL_CST
    2020                 :           0 :            && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0)))
    2021                 :           1 :           || REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1))))
    2022                 :           0 :     return NULL_TREE;
    2023                 :             : 
    2024                 :             :   /* If the exponent is equivalent to an integer, expand to an optimal
    2025                 :             :      multiplication sequence when profitable.  */
    2026                 :         356 :   c = TREE_REAL_CST (arg1);
    2027                 :         356 :   n = real_to_integer (&c);
    2028                 :         356 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2029                 :         356 :   c_is_int = real_identical (&c, &cint);
    2030                 :             : 
    2031                 :         356 :   if (c_is_int
    2032                 :         356 :       && ((n >= -1 && n <= 2)
    2033                 :          66 :           || (flag_unsafe_math_optimizations
    2034                 :          11 :               && speed_p
    2035                 :          11 :               && powi_cost (n) <= POWI_MAX_MULTS)))
    2036                 :          50 :     return gimple_expand_builtin_powi (gsi, loc, arg0, n);
    2037                 :             : 
    2038                 :             :   /* Attempt various optimizations using sqrt and cbrt.  */
    2039                 :         306 :   type = TREE_TYPE (arg0);
    2040                 :         306 :   mode = TYPE_MODE (type);
    2041                 :         306 :   sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
    2042                 :             : 
    2043                 :             :   /* Optimize pow(x,0.5) = sqrt(x).  This replacement is always safe
    2044                 :             :      unless signed zeros must be maintained.  pow(-0,0.5) = +0, while
    2045                 :             :      sqrt(-0) = -0.  */
    2046                 :         306 :   if (sqrtfn
    2047                 :         306 :       && real_equal (&c, &dconsthalf)
    2048                 :         314 :       && !HONOR_SIGNED_ZEROS (mode))
    2049                 :           0 :     return build_and_insert_call (gsi, loc, sqrtfn, arg0);
    2050                 :             : 
    2051                 :         306 :   hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing;
    2052                 :             : 
    2053                 :             :   /* Optimize pow(x,1./3.) = cbrt(x).  This requires unsafe math
    2054                 :             :      optimizations since 1./3. is not exactly representable.  If x
    2055                 :             :      is negative and finite, the correct value of pow(x,1./3.) is
    2056                 :             :      a NaN with the "invalid" exception raised, because the value
    2057                 :             :      of 1./3. actually has an even denominator.  The correct value
    2058                 :             :      of cbrt(x) is a negative real value.  */
    2059                 :         306 :   cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
    2060                 :         306 :   dconst1_3 = real_value_truncate (mode, dconst_third ());
    2061                 :             : 
    2062                 :         306 :   if (flag_unsafe_math_optimizations
    2063                 :          26 :       && cbrtfn
    2064                 :          26 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2065                 :         332 :       && real_equal (&c, &dconst1_3))
    2066                 :           0 :     return build_and_insert_call (gsi, loc, cbrtfn, arg0);
    2067                 :             : 
    2068                 :             :   /* Optimize pow(x,1./6.) = cbrt(sqrt(x)).  Don't do this optimization
    2069                 :             :      if we don't have a hardware sqrt insn.  */
    2070                 :         306 :   dconst1_6 = dconst1_3;
    2071                 :         306 :   SET_REAL_EXP (&dconst1_6, REAL_EXP (&dconst1_6) - 1);
    2072                 :             : 
    2073                 :         306 :   if (flag_unsafe_math_optimizations
    2074                 :          26 :       && sqrtfn
    2075                 :          26 :       && cbrtfn
    2076                 :          26 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2077                 :             :       && speed_p
    2078                 :          26 :       && hw_sqrt_exists
    2079                 :         332 :       && real_equal (&c, &dconst1_6))
    2080                 :             :     {
    2081                 :             :       /* sqrt(x)  */
    2082                 :           0 :       sqrt_arg0 = build_and_insert_call (gsi, loc, sqrtfn, arg0);
    2083                 :             : 
    2084                 :             :       /* cbrt(sqrt(x))  */
    2085                 :           0 :       return build_and_insert_call (gsi, loc, cbrtfn, sqrt_arg0);
    2086                 :             :     }
    2087                 :             : 
    2088                 :             : 
    2089                 :             :   /* Attempt to expand the POW as a product of square root chains.
    2090                 :             :      Expand the 0.25 case even when otpimising for size.  */
    2091                 :         306 :   if (flag_unsafe_math_optimizations
    2092                 :          26 :       && sqrtfn
    2093                 :          26 :       && hw_sqrt_exists
    2094                 :          26 :       && (speed_p || real_equal (&c, &dconst1_4))
    2095                 :         332 :       && !HONOR_SIGNED_ZEROS (mode))
    2096                 :             :     {
    2097                 :          52 :       unsigned int max_depth = speed_p
    2098                 :          26 :                                 ? param_max_pow_sqrt_depth
    2099                 :             :                                 : 2;
    2100                 :             : 
    2101                 :          26 :       tree expand_with_sqrts
    2102                 :          26 :         = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth);
    2103                 :             : 
    2104                 :          26 :       if (expand_with_sqrts)
    2105                 :             :         return expand_with_sqrts;
    2106                 :             :     }
    2107                 :             : 
    2108                 :         287 :   real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
    2109                 :         287 :   n = real_to_integer (&c2);
    2110                 :         287 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2111                 :         287 :   c2_is_int = real_identical (&c2, &cint);
    2112                 :             : 
    2113                 :             :   /* Optimize pow(x,c), where 3c = n for some nonzero integer n, into
    2114                 :             : 
    2115                 :             :      powi(x, n/3) * powi(cbrt(x), n%3),                    n > 0;
    2116                 :             :      1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)),  n < 0.
    2117                 :             : 
    2118                 :             :      Do not calculate the first factor when n/3 = 0.  As cbrt(x) is
    2119                 :             :      different from pow(x, 1./3.) due to rounding and behavior with
    2120                 :             :      negative x, we need to constrain this transformation to unsafe
    2121                 :             :      math and positive x or finite math.  */
    2122                 :         287 :   real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
    2123                 :         287 :   real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
    2124                 :         287 :   real_round (&c2, mode, &c2);
    2125                 :         287 :   n = real_to_integer (&c2);
    2126                 :         287 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2127                 :         287 :   real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
    2128                 :         287 :   real_convert (&c2, mode, &c2);
    2129                 :             : 
    2130                 :         287 :   if (flag_unsafe_math_optimizations
    2131                 :           7 :       && cbrtfn
    2132                 :           7 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2133                 :           7 :       && real_identical (&c2, &c)
    2134                 :           4 :       && !c2_is_int
    2135                 :           4 :       && optimize_function_for_speed_p (cfun)
    2136                 :         291 :       && powi_cost (n / 3) <= POWI_MAX_MULTS)
    2137                 :             :     {
    2138                 :           4 :       tree powi_x_ndiv3 = NULL_TREE;
    2139                 :             : 
    2140                 :             :       /* Attempt to fold powi(arg0, abs(n/3)) into multiplies.  If not
    2141                 :             :          possible or profitable, give up.  Skip the degenerate case when
    2142                 :             :          abs(n) < 3, where the result is always 1.  */
    2143                 :           4 :       if (absu_hwi (n) >= 3)
    2144                 :             :         {
    2145                 :           4 :           powi_x_ndiv3 = gimple_expand_builtin_powi (gsi, loc, arg0,
    2146                 :             :                                                      abs_hwi (n / 3));
    2147                 :           4 :           if (!powi_x_ndiv3)
    2148                 :             :             return NULL_TREE;
    2149                 :             :         }
    2150                 :             : 
    2151                 :             :       /* Calculate powi(cbrt(x), n%3).  Don't use gimple_expand_builtin_powi
    2152                 :             :          as that creates an unnecessary variable.  Instead, just produce
    2153                 :             :          either cbrt(x) or cbrt(x) * cbrt(x).  */
    2154                 :           4 :       cbrt_x = build_and_insert_call (gsi, loc, cbrtfn, arg0);
    2155                 :             : 
    2156                 :           4 :       if (absu_hwi (n) % 3 == 1)
    2157                 :             :         powi_cbrt_x = cbrt_x;
    2158                 :             :       else
    2159                 :           2 :         powi_cbrt_x = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    2160                 :             :                                               cbrt_x, cbrt_x);
    2161                 :             : 
    2162                 :             :       /* Multiply the two subexpressions, unless powi(x,abs(n)/3) = 1.  */
    2163                 :           4 :       if (absu_hwi (n) < 3)
    2164                 :             :         result = powi_cbrt_x;
    2165                 :             :       else
    2166                 :           4 :         result = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    2167                 :             :                                          powi_x_ndiv3, powi_cbrt_x);
    2168                 :             : 
    2169                 :             :       /* If n is negative, reciprocate the result.  */
    2170                 :           4 :       if (n < 0)
    2171                 :           1 :         result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
    2172                 :             :                                          build_real (type, dconst1), result);
    2173                 :             : 
    2174                 :           4 :       return result;
    2175                 :             :     }
    2176                 :             : 
    2177                 :             :   /* No optimizations succeeded.  */
    2178                 :             :   return NULL_TREE;
    2179                 :             : }
    2180                 :             : 
    2181                 :             : /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
    2182                 :             :    on the SSA_NAME argument of each of them.  */
    2183                 :             : 
    2184                 :             : namespace {
    2185                 :             : 
    2186                 :             : const pass_data pass_data_cse_sincos =
    2187                 :             : {
    2188                 :             :   GIMPLE_PASS, /* type */
    2189                 :             :   "sincos", /* name */
    2190                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    2191                 :             :   TV_TREE_SINCOS, /* tv_id */
    2192                 :             :   PROP_ssa, /* properties_required */
    2193                 :             :   0, /* properties_provided */
    2194                 :             :   0, /* properties_destroyed */
    2195                 :             :   0, /* todo_flags_start */
    2196                 :             :   TODO_update_ssa, /* todo_flags_finish */
    2197                 :             : };
    2198                 :             : 
    2199                 :             : class pass_cse_sincos : public gimple_opt_pass
    2200                 :             : {
    2201                 :             : public:
    2202                 :      282866 :   pass_cse_sincos (gcc::context *ctxt)
    2203                 :      565732 :     : gimple_opt_pass (pass_data_cse_sincos, ctxt)
    2204                 :             :   {}
    2205                 :             : 
    2206                 :             :   /* opt_pass methods: */
    2207                 :     1000974 :   bool gate (function *) final override
    2208                 :             :     {
    2209                 :     1000974 :       return optimize;
    2210                 :             :     }
    2211                 :             : 
    2212                 :             :   unsigned int execute (function *) final override;
    2213                 :             : 
    2214                 :             : }; // class pass_cse_sincos
    2215                 :             : 
    2216                 :             : unsigned int
    2217                 :     1000952 : pass_cse_sincos::execute (function *fun)
    2218                 :             : {
    2219                 :     1000952 :   basic_block bb;
    2220                 :     1000952 :   bool cfg_changed = false;
    2221                 :             : 
    2222                 :     1000952 :   calculate_dominance_info (CDI_DOMINATORS);
    2223                 :     1000952 :   memset (&sincos_stats, 0, sizeof (sincos_stats));
    2224                 :             : 
    2225                 :    10610405 :   FOR_EACH_BB_FN (bb, fun)
    2226                 :             :     {
    2227                 :     9609453 :       gimple_stmt_iterator gsi;
    2228                 :             : 
    2229                 :    83360824 :       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    2230                 :             :         {
    2231                 :    73751371 :           gimple *stmt = gsi_stmt (gsi);
    2232                 :             : 
    2233                 :    73751371 :           if (is_gimple_call (stmt)
    2234                 :    73751371 :               && gimple_call_lhs (stmt))
    2235                 :             :             {
    2236                 :     1950677 :               tree arg;
    2237                 :     1950677 :               switch (gimple_call_combined_fn (stmt))
    2238                 :             :                 {
    2239                 :        1029 :                 CASE_CFN_COS:
    2240                 :        1029 :                 CASE_CFN_SIN:
    2241                 :        1029 :                 CASE_CFN_CEXPI:
    2242                 :        1029 :                   arg = gimple_call_arg (stmt, 0);
    2243                 :             :                   /* Make sure we have either sincos or cexp.  */
    2244                 :        1029 :                   if (!targetm.libc_has_function (function_c99_math_complex,
    2245                 :        1029 :                                                   TREE_TYPE (arg))
    2246                 :        1029 :                       && !targetm.libc_has_function (function_sincos,
    2247                 :           0 :                                                      TREE_TYPE (arg)))
    2248                 :             :                     break;
    2249                 :             : 
    2250                 :        1029 :                   if (TREE_CODE (arg) == SSA_NAME)
    2251                 :        1029 :                     cfg_changed |= execute_cse_sincos_1 (arg);
    2252                 :             :                   break;
    2253                 :             :                 default:
    2254                 :             :                   break;
    2255                 :             :                 }
    2256                 :             :             }
    2257                 :             :         }
    2258                 :             :     }
    2259                 :             : 
    2260                 :     1000952 :   statistics_counter_event (fun, "sincos statements inserted",
    2261                 :             :                             sincos_stats.inserted);
    2262                 :     1000952 :   statistics_counter_event (fun, "conv statements removed",
    2263                 :             :                             sincos_stats.conv_removed);
    2264                 :             : 
    2265                 :     1000952 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    2266                 :             : }
    2267                 :             : 
    2268                 :             : } // anon namespace
    2269                 :             : 
    2270                 :             : gimple_opt_pass *
    2271                 :      282866 : make_pass_cse_sincos (gcc::context *ctxt)
    2272                 :             : {
    2273                 :      282866 :   return new pass_cse_sincos (ctxt);
    2274                 :             : }
    2275                 :             : 
    2276                 :             : /* Expand powi(x,n) into an optimal number of multiplies, when n is a
    2277                 :             :    constant.  */
    2278                 :             : namespace {
    2279                 :             : 
    2280                 :             : const pass_data pass_data_expand_pow =
    2281                 :             : {
    2282                 :             :   GIMPLE_PASS, /* type */
    2283                 :             :   "pow", /* name */
    2284                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    2285                 :             :   TV_TREE_POW, /* tv_id */
    2286                 :             :   PROP_ssa, /* properties_required */
    2287                 :             :   PROP_gimple_opt_math, /* properties_provided */
    2288                 :             :   0, /* properties_destroyed */
    2289                 :             :   0, /* todo_flags_start */
    2290                 :             :   TODO_update_ssa, /* todo_flags_finish */
    2291                 :             : };
    2292                 :             : 
    2293                 :             : class pass_expand_pow : public gimple_opt_pass
    2294                 :             : {
    2295                 :             : public:
    2296                 :      282866 :   pass_expand_pow (gcc::context *ctxt)
    2297                 :      565732 :     : gimple_opt_pass (pass_data_expand_pow, ctxt)
    2298                 :             :   {}
    2299                 :             : 
    2300                 :             :   /* opt_pass methods: */
    2301                 :     1000974 :   bool gate (function *) final override
    2302                 :             :     {
    2303                 :     1000974 :       return optimize;
    2304                 :             :     }
    2305                 :             : 
    2306                 :             :   unsigned int execute (function *) final override;
    2307                 :             : 
    2308                 :             : }; // class pass_expand_pow
    2309                 :             : 
    2310                 :             : unsigned int
    2311                 :     1000969 : pass_expand_pow::execute (function *fun)
    2312                 :             : {
    2313                 :     1000969 :   basic_block bb;
    2314                 :     1000969 :   bool cfg_changed = false;
    2315                 :             : 
    2316                 :     1000969 :   calculate_dominance_info (CDI_DOMINATORS);
    2317                 :             : 
    2318                 :     9854659 :   FOR_EACH_BB_FN (bb, fun)
    2319                 :             :     {
    2320                 :     8853690 :       gimple_stmt_iterator gsi;
    2321                 :     8853690 :       bool cleanup_eh = false;
    2322                 :             : 
    2323                 :    80561316 :       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    2324                 :             :         {
    2325                 :    71707626 :           gimple *stmt = gsi_stmt (gsi);
    2326                 :             : 
    2327                 :             :           /* Only the last stmt in a bb could throw, no need to call
    2328                 :             :              gimple_purge_dead_eh_edges if we change something in the middle
    2329                 :             :              of a basic block.  */
    2330                 :    71707626 :           cleanup_eh = false;
    2331                 :             : 
    2332                 :    71707626 :           if (is_gimple_call (stmt)
    2333                 :    71707626 :               && gimple_call_lhs (stmt))
    2334                 :             :             {
    2335                 :     1924904 :               tree arg0, arg1, result;
    2336                 :     1924904 :               HOST_WIDE_INT n;
    2337                 :     1924904 :               location_t loc;
    2338                 :             : 
    2339                 :     1924904 :               switch (gimple_call_combined_fn (stmt))
    2340                 :             :                 {
    2341                 :         595 :                 CASE_CFN_POW:
    2342                 :         595 :                   arg0 = gimple_call_arg (stmt, 0);
    2343                 :         595 :                   arg1 = gimple_call_arg (stmt, 1);
    2344                 :             : 
    2345                 :         595 :                   loc = gimple_location (stmt);
    2346                 :         595 :                   result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
    2347                 :             : 
    2348                 :         595 :                   if (result)
    2349                 :             :                     {
    2350                 :          73 :                       tree lhs = gimple_get_lhs (stmt);
    2351                 :          73 :                       gassign *new_stmt = gimple_build_assign (lhs, result);
    2352                 :          73 :                       gimple_set_location (new_stmt, loc);
    2353                 :          73 :                       unlink_stmt_vdef (stmt);
    2354                 :          73 :                       gsi_replace (&gsi, new_stmt, true);
    2355                 :          73 :                       cleanup_eh = true;
    2356                 :         146 :                       if (gimple_vdef (stmt))
    2357                 :          21 :                         release_ssa_name (gimple_vdef (stmt));
    2358                 :             :                     }
    2359                 :             :                   break;
    2360                 :             : 
    2361                 :         857 :                 CASE_CFN_POWI:
    2362                 :         857 :                   arg0 = gimple_call_arg (stmt, 0);
    2363                 :         857 :                   arg1 = gimple_call_arg (stmt, 1);
    2364                 :         857 :                   loc = gimple_location (stmt);
    2365                 :             : 
    2366                 :         857 :                   if (real_minus_onep (arg0))
    2367                 :             :                     {
    2368                 :          11 :                       tree t0, t1, cond, one, minus_one;
    2369                 :          11 :                       gassign *stmt;
    2370                 :             : 
    2371                 :          11 :                       t0 = TREE_TYPE (arg0);
    2372                 :          11 :                       t1 = TREE_TYPE (arg1);
    2373                 :          11 :                       one = build_real (t0, dconst1);
    2374                 :          11 :                       minus_one = build_real (t0, dconstm1);
    2375                 :             : 
    2376                 :          11 :                       cond = make_temp_ssa_name (t1, NULL, "powi_cond");
    2377                 :          11 :                       stmt = gimple_build_assign (cond, BIT_AND_EXPR,
    2378                 :          11 :                                                   arg1, build_int_cst (t1, 1));
    2379                 :          11 :                       gimple_set_location (stmt, loc);
    2380                 :          11 :                       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    2381                 :             : 
    2382                 :          11 :                       result = make_temp_ssa_name (t0, NULL, "powi");
    2383                 :          11 :                       stmt = gimple_build_assign (result, COND_EXPR, cond,
    2384                 :             :                                                   minus_one, one);
    2385                 :          11 :                       gimple_set_location (stmt, loc);
    2386                 :          11 :                       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    2387                 :             :                     }
    2388                 :             :                   else
    2389                 :             :                     {
    2390                 :         846 :                       if (!tree_fits_shwi_p (arg1))
    2391                 :             :                         break;
    2392                 :             : 
    2393                 :         603 :                       n = tree_to_shwi (arg1);
    2394                 :         603 :                       result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
    2395                 :             :                     }
    2396                 :             : 
    2397                 :         614 :                   if (result)
    2398                 :             :                     {
    2399                 :         606 :                       tree lhs = gimple_get_lhs (stmt);
    2400                 :         606 :                       gassign *new_stmt = gimple_build_assign (lhs, result);
    2401                 :         606 :                       gimple_set_location (new_stmt, loc);
    2402                 :         606 :                       unlink_stmt_vdef (stmt);
    2403                 :         606 :                       gsi_replace (&gsi, new_stmt, true);
    2404                 :         606 :                       cleanup_eh = true;
    2405                 :    71708838 :                       if (gimple_vdef (stmt))
    2406                 :           0 :                         release_ssa_name (gimple_vdef (stmt));
    2407                 :             :                     }
    2408                 :             :                   break;
    2409                 :             : 
    2410                 :         243 :                 default:;
    2411                 :             :                 }
    2412                 :             :             }
    2413                 :             :         }
    2414                 :     8853690 :       if (cleanup_eh)
    2415                 :           1 :         cfg_changed |= gimple_purge_dead_eh_edges (bb);
    2416                 :             :     }
    2417                 :             : 
    2418                 :     1000969 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    2419                 :             : }
    2420                 :             : 
    2421                 :             : } // anon namespace
    2422                 :             : 
    2423                 :             : gimple_opt_pass *
    2424                 :      282866 : make_pass_expand_pow (gcc::context *ctxt)
    2425                 :             : {
    2426                 :      282866 :   return new pass_expand_pow (ctxt);
    2427                 :             : }
    2428                 :             : 
    2429                 :             : /* Return true if stmt is a type conversion operation that can be stripped
    2430                 :             :    when used in a widening multiply operation.  */
    2431                 :             : static bool
    2432                 :      409165 : widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
    2433                 :             : {
    2434                 :      409165 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    2435                 :             : 
    2436                 :      409165 :   if (TREE_CODE (result_type) == INTEGER_TYPE)
    2437                 :             :     {
    2438                 :      409165 :       tree op_type;
    2439                 :      409165 :       tree inner_op_type;
    2440                 :             : 
    2441                 :      409165 :       if (!CONVERT_EXPR_CODE_P (rhs_code))
    2442                 :             :         return false;
    2443                 :             : 
    2444                 :      169595 :       op_type = TREE_TYPE (gimple_assign_lhs (stmt));
    2445                 :             : 
    2446                 :             :       /* If the type of OP has the same precision as the result, then
    2447                 :             :          we can strip this conversion.  The multiply operation will be
    2448                 :             :          selected to create the correct extension as a by-product.  */
    2449                 :      169595 :       if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type))
    2450                 :             :         return true;
    2451                 :             : 
    2452                 :             :       /* We can also strip a conversion if it preserves the signed-ness of
    2453                 :             :          the operation and doesn't narrow the range.  */
    2454                 :        1157 :       inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
    2455                 :             : 
    2456                 :             :       /* If the inner-most type is unsigned, then we can strip any
    2457                 :             :          intermediate widening operation.  If it's signed, then the
    2458                 :             :          intermediate widening operation must also be signed.  */
    2459                 :        1157 :       if ((TYPE_UNSIGNED (inner_op_type)
    2460                 :        1156 :            || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type))
    2461                 :        2313 :           && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type))
    2462                 :             :         return true;
    2463                 :             : 
    2464                 :        1157 :       return false;
    2465                 :             :     }
    2466                 :             : 
    2467                 :           0 :   return rhs_code == FIXED_CONVERT_EXPR;
    2468                 :             : }
    2469                 :             : 
    2470                 :             : /* Return true if RHS is a suitable operand for a widening multiplication,
    2471                 :             :    assuming a target type of TYPE.
    2472                 :             :    There are two cases:
    2473                 :             : 
    2474                 :             :      - RHS makes some value at least twice as wide.  Store that value
    2475                 :             :        in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.
    2476                 :             : 
    2477                 :             :      - RHS is an integer constant.  Store that value in *NEW_RHS_OUT if so,
    2478                 :             :        but leave *TYPE_OUT untouched.  */
    2479                 :             : 
    2480                 :             : static bool
    2481                 :      845401 : is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
    2482                 :             :                         tree *new_rhs_out)
    2483                 :             : {
    2484                 :      845401 :   gimple *stmt;
    2485                 :      845401 :   tree type1, rhs1;
    2486                 :             : 
    2487                 :      845401 :   if (TREE_CODE (rhs) == SSA_NAME)
    2488                 :             :     {
    2489                 :             :       /* Use tree_non_zero_bits to see if this operand is zero_extended
    2490                 :             :          for unsigned widening multiplications or non-negative for
    2491                 :             :          signed widening multiplications.  */
    2492                 :      695691 :       if (TREE_CODE (type) == INTEGER_TYPE
    2493                 :      695691 :           && (TYPE_PRECISION (type) & 1) == 0
    2494                 :     1391382 :           && int_mode_for_size (TYPE_PRECISION (type) / 2, 1).exists ())
    2495                 :             :         {
    2496                 :      690201 :           unsigned int prec = TYPE_PRECISION (type);
    2497                 :      690201 :           unsigned int hprec = prec / 2;
    2498                 :      690201 :           wide_int bits = wide_int::from (tree_nonzero_bits (rhs), prec,
    2499                 :     1380402 :                                           TYPE_SIGN (TREE_TYPE (rhs)));
    2500                 :      690201 :           if (TYPE_UNSIGNED (type)
    2501                 :     1189421 :               && wi::bit_and (bits, wi::mask (hprec, true, prec)) == 0)
    2502                 :             :             {
    2503                 :      139726 :               *type_out = build_nonstandard_integer_type (hprec, true);
    2504                 :             :               /* X & MODE_MASK can be simplified to (T)X.  */
    2505                 :      139726 :               stmt = SSA_NAME_DEF_STMT (rhs);
    2506                 :      279452 :               if (is_gimple_assign (stmt)
    2507                 :      123145 :                   && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
    2508                 :       16832 :                   && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
    2509                 :      172790 :                   && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
    2510                 :       16532 :                                      prec, TYPE_SIGN (TREE_TYPE (rhs)))
    2511                 :      189322 :                      == wi::mask (hprec, false, prec))
    2512                 :       14625 :                 *new_rhs_out = gimple_assign_rhs1 (stmt);
    2513                 :             :               else
    2514                 :      125101 :                 *new_rhs_out = rhs;
    2515                 :      139726 :               return true;
    2516                 :             :             }
    2517                 :      550475 :           else if (!TYPE_UNSIGNED (type)
    2518                 :      741456 :                    && wi::bit_and (bits, wi::mask (hprec - 1, true, prec)) == 0)
    2519                 :             :             {
    2520                 :       26520 :               *type_out = build_nonstandard_integer_type (hprec, false);
    2521                 :       26520 :               *new_rhs_out = rhs;
    2522                 :       26520 :               return true;
    2523                 :             :             }
    2524                 :      690201 :         }
    2525                 :             : 
    2526                 :      529445 :       stmt = SSA_NAME_DEF_STMT (rhs);
    2527                 :      529445 :       if (is_gimple_assign (stmt))
    2528                 :             :         {
    2529                 :             : 
    2530                 :      409165 :           if (widening_mult_conversion_strippable_p (type, stmt))
    2531                 :             :             {
    2532                 :      168438 :               rhs1 = gimple_assign_rhs1 (stmt);
    2533                 :             : 
    2534                 :      168438 :               if (TREE_CODE (rhs1) == INTEGER_CST)
    2535                 :             :                 {
    2536                 :           0 :                   *new_rhs_out = rhs1;
    2537                 :           0 :                   *type_out = NULL;
    2538                 :           0 :                   return true;
    2539                 :             :                 }
    2540                 :             :             }
    2541                 :             :           else
    2542                 :             :             rhs1 = rhs;
    2543                 :             :         }
    2544                 :             :       else
    2545                 :             :         rhs1 = rhs;
    2546                 :             : 
    2547                 :      529445 :       type1 = TREE_TYPE (rhs1);
    2548                 :             : 
    2549                 :      529445 :       if (TREE_CODE (type1) != TREE_CODE (type)
    2550                 :      529445 :           || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
    2551                 :             :         return false;
    2552                 :             : 
    2553                 :       57723 :       *new_rhs_out = rhs1;
    2554                 :       57723 :       *type_out = type1;
    2555                 :       57723 :       return true;
    2556                 :             :     }
    2557                 :             : 
    2558                 :      149710 :   if (TREE_CODE (rhs) == INTEGER_CST)
    2559                 :             :     {
    2560                 :      149710 :       *new_rhs_out = rhs;
    2561                 :      149710 :       *type_out = NULL;
    2562                 :      149710 :       return true;
    2563                 :             :     }
    2564                 :             : 
    2565                 :             :   return false;
    2566                 :             : }
    2567                 :             : 
    2568                 :             : /* Return true if STMT performs a widening multiplication, assuming the
    2569                 :             :    output type is TYPE.  If so, store the unwidened types of the operands
    2570                 :             :    in *TYPE1_OUT and *TYPE2_OUT respectively.  Also fill *RHS1_OUT and
    2571                 :             :    *RHS2_OUT such that converting those operands to types *TYPE1_OUT
    2572                 :             :    and *TYPE2_OUT would give the operands of the multiplication.  */
    2573                 :             : 
    2574                 :             : static bool
    2575                 :      655698 : is_widening_mult_p (gimple *stmt,
    2576                 :             :                     tree *type1_out, tree *rhs1_out,
    2577                 :             :                     tree *type2_out, tree *rhs2_out)
    2578                 :             : {
    2579                 :      655698 :   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
    2580                 :             : 
    2581                 :      655698 :   if (TREE_CODE (type) == INTEGER_TYPE)
    2582                 :             :     {
    2583                 :      655698 :       if (TYPE_OVERFLOW_TRAPS (type))
    2584                 :             :         return false;
    2585                 :             :     }
    2586                 :           0 :   else if (TREE_CODE (type) != FIXED_POINT_TYPE)
    2587                 :             :     return false;
    2588                 :             : 
    2589                 :      655670 :   if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
    2590                 :             :                                rhs1_out))
    2591                 :             :     return false;
    2592                 :             : 
    2593                 :      189731 :   if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
    2594                 :             :                                rhs2_out))
    2595                 :             :     return false;
    2596                 :             : 
    2597                 :      183948 :   if (*type1_out == NULL)
    2598                 :             :     {
    2599                 :           0 :       if (*type2_out == NULL || !int_fits_type_p (*rhs1_out, *type2_out))
    2600                 :             :         return false;
    2601                 :           0 :       *type1_out = *type2_out;
    2602                 :             :     }
    2603                 :             : 
    2604                 :      183948 :   if (*type2_out == NULL)
    2605                 :             :     {
    2606                 :      149710 :       if (!int_fits_type_p (*rhs2_out, *type1_out))
    2607                 :             :         return false;
    2608                 :      145032 :       *type2_out = *type1_out;
    2609                 :             :     }
    2610                 :             : 
    2611                 :             :   /* Ensure that the larger of the two operands comes first. */
    2612                 :      179270 :   if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out))
    2613                 :             :     {
    2614                 :          80 :       std::swap (*type1_out, *type2_out);
    2615                 :          80 :       std::swap (*rhs1_out, *rhs2_out);
    2616                 :             :     }
    2617                 :             : 
    2618                 :             :   return true;
    2619                 :             : }
    2620                 :             : 
    2621                 :             : /* Check to see if the CALL statement is an invocation of copysign
    2622                 :             :    with 1. being the first argument.  */
    2623                 :             : static bool
    2624                 :      149934 : is_copysign_call_with_1 (gimple *call)
    2625                 :             : {
    2626                 :      154918 :   gcall *c = dyn_cast <gcall *> (call);
    2627                 :        5040 :   if (! c)
    2628                 :             :     return false;
    2629                 :             : 
    2630                 :        5040 :   enum combined_fn code = gimple_call_combined_fn (c);
    2631                 :             : 
    2632                 :        5040 :   if (code == CFN_LAST)
    2633                 :             :     return false;
    2634                 :             : 
    2635                 :        4138 :   if (builtin_fn_p (code))
    2636                 :             :     {
    2637                 :        1193 :       switch (as_builtin_fn (code))
    2638                 :             :         {
    2639                 :          30 :         CASE_FLT_FN (BUILT_IN_COPYSIGN):
    2640                 :          30 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
    2641                 :          30 :           return real_onep (gimple_call_arg (c, 0));
    2642                 :             :         default:
    2643                 :             :           return false;
    2644                 :             :         }
    2645                 :             :     }
    2646                 :             : 
    2647                 :        2945 :   if (internal_fn_p (code))
    2648                 :             :     {
    2649                 :        2945 :       switch (as_internal_fn (code))
    2650                 :             :         {
    2651                 :          26 :         case IFN_COPYSIGN:
    2652                 :          26 :           return real_onep (gimple_call_arg (c, 0));
    2653                 :             :         default:
    2654                 :             :           return false;
    2655                 :             :         }
    2656                 :             :     }
    2657                 :             : 
    2658                 :             :    return false;
    2659                 :             : }
    2660                 :             : 
    2661                 :             : /* Try to expand the pattern x * copysign (1, y) into xorsign (x, y).
    2662                 :             :    This only happens when the xorsign optab is defined, if the
    2663                 :             :    pattern is not a xorsign pattern or if expansion fails FALSE is
    2664                 :             :    returned, otherwise TRUE is returned.  */
    2665                 :             : static bool
    2666                 :      652732 : convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
    2667                 :             : {
    2668                 :      652732 :   tree treeop0, treeop1, lhs, type;
    2669                 :      652732 :   location_t loc = gimple_location (stmt);
    2670                 :      652732 :   lhs = gimple_assign_lhs (stmt);
    2671                 :      652732 :   treeop0 = gimple_assign_rhs1 (stmt);
    2672                 :      652732 :   treeop1 = gimple_assign_rhs2 (stmt);
    2673                 :      652732 :   type = TREE_TYPE (lhs);
    2674                 :      652732 :   machine_mode mode = TYPE_MODE (type);
    2675                 :             : 
    2676                 :      652732 :   if (HONOR_SNANS (type))
    2677                 :             :     return false;
    2678                 :             : 
    2679                 :      652640 :   if (TREE_CODE (treeop0) == SSA_NAME && TREE_CODE (treeop1) == SSA_NAME)
    2680                 :             :     {
    2681                 :      207588 :       gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
    2682                 :      207588 :       if (!has_single_use (treeop0) || !is_copysign_call_with_1 (call0))
    2683                 :             :         {
    2684                 :      207562 :           call0 = SSA_NAME_DEF_STMT (treeop1);
    2685                 :      207562 :           if (!has_single_use (treeop1) || !is_copysign_call_with_1 (call0))
    2686                 :      207542 :             return false;
    2687                 :             : 
    2688                 :             :           treeop1 = treeop0;
    2689                 :             :         }
    2690                 :          46 :         if (optab_handler (xorsign_optab, mode) == CODE_FOR_nothing)
    2691                 :             :           return false;
    2692                 :             : 
    2693                 :          46 :         gcall *c = as_a<gcall*> (call0);
    2694                 :          46 :         treeop0 = gimple_call_arg (c, 1);
    2695                 :             : 
    2696                 :          46 :         gcall *call_stmt
    2697                 :          46 :           = gimple_build_call_internal (IFN_XORSIGN, 2, treeop1, treeop0);
    2698                 :          46 :         gimple_set_lhs (call_stmt, lhs);
    2699                 :          46 :         gimple_set_location (call_stmt, loc);
    2700                 :          46 :         gsi_replace (gsi, call_stmt, true);
    2701                 :          46 :         return true;
    2702                 :             :     }
    2703                 :             : 
    2704                 :             :   return false;
    2705                 :             : }
    2706                 :             : 
    2707                 :             : /* Process a single gimple statement STMT, which has a MULT_EXPR as
    2708                 :             :    its rhs, and try to convert it into a WIDEN_MULT_EXPR.  The return
    2709                 :             :    value is true iff we converted the statement.  */
    2710                 :             : 
    2711                 :             : static bool
    2712                 :      662934 : convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
    2713                 :             : {
    2714                 :      662934 :   tree lhs, rhs1, rhs2, type, type1, type2;
    2715                 :      662934 :   enum insn_code handler;
    2716                 :      662934 :   scalar_int_mode to_mode, from_mode, actual_mode;
    2717                 :      662934 :   optab op;
    2718                 :      662934 :   int actual_precision;
    2719                 :      662934 :   location_t loc = gimple_location (stmt);
    2720                 :      662934 :   bool from_unsigned1, from_unsigned2;
    2721                 :             : 
    2722                 :      662934 :   lhs = gimple_assign_lhs (stmt);
    2723                 :      662934 :   type = TREE_TYPE (lhs);
    2724                 :      662934 :   if (TREE_CODE (type) != INTEGER_TYPE)
    2725                 :             :     return false;
    2726                 :             : 
    2727                 :      527688 :   if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))
    2728                 :             :     return false;
    2729                 :             : 
    2730                 :             :   /* if any one of rhs1 and rhs2 is subject to abnormal coalescing,
    2731                 :             :      avoid the tranform. */
    2732                 :      145225 :   if ((TREE_CODE (rhs1) == SSA_NAME
    2733                 :      145225 :        && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
    2734                 :      290449 :       || (TREE_CODE (rhs2) == SSA_NAME
    2735                 :       23896 :           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)))
    2736                 :             :     return false;
    2737                 :             : 
    2738                 :      145224 :   to_mode = SCALAR_INT_TYPE_MODE (type);
    2739                 :      145224 :   from_mode = SCALAR_INT_TYPE_MODE (type1);
    2740                 :      145224 :   if (to_mode == from_mode)
    2741                 :             :     return false;
    2742                 :             : 
    2743                 :      145220 :   from_unsigned1 = TYPE_UNSIGNED (type1);
    2744                 :      145220 :   from_unsigned2 = TYPE_UNSIGNED (type2);
    2745                 :             : 
    2746                 :      145220 :   if (from_unsigned1 && from_unsigned2)
    2747                 :             :     op = umul_widen_optab;
    2748                 :       56448 :   else if (!from_unsigned1 && !from_unsigned2)
    2749                 :             :     op = smul_widen_optab;
    2750                 :             :   else
    2751                 :        1905 :     op = usmul_widen_optab;
    2752                 :             : 
    2753                 :      145220 :   handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
    2754                 :             :                                                   &actual_mode);
    2755                 :             : 
    2756                 :      145220 :   if (handler == CODE_FOR_nothing)
    2757                 :             :     {
    2758                 :      135018 :       if (op != smul_widen_optab)
    2759                 :             :         {
    2760                 :             :           /* We can use a signed multiply with unsigned types as long as
    2761                 :             :              there is a wider mode to use, or it is the smaller of the two
    2762                 :             :              types that is unsigned.  Note that type1 >= type2, always.  */
    2763                 :       81961 :           if ((TYPE_UNSIGNED (type1)
    2764                 :       80240 :                && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
    2765                 :       81961 :               || (TYPE_UNSIGNED (type2)
    2766                 :        1721 :                   && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
    2767                 :             :             {
    2768                 :       81961 :               if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
    2769                 :      163922 :                   || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
    2770                 :       81961 :                 return false;
    2771                 :             :             }
    2772                 :             : 
    2773                 :           0 :           op = smul_widen_optab;
    2774                 :           0 :           handler = find_widening_optab_handler_and_mode (op, to_mode,
    2775                 :             :                                                           from_mode,
    2776                 :             :                                                           &actual_mode);
    2777                 :             : 
    2778                 :           0 :           if (handler == CODE_FOR_nothing)
    2779                 :             :             return false;
    2780                 :             : 
    2781                 :             :           from_unsigned1 = from_unsigned2 = false;
    2782                 :             :         }
    2783                 :             :       else
    2784                 :             :         {
    2785                 :             :           /* Expand can synthesize smul_widen_optab if the target
    2786                 :             :              supports umul_widen_optab.  */
    2787                 :       53057 :           op = umul_widen_optab;
    2788                 :       53057 :           handler = find_widening_optab_handler_and_mode (op, to_mode,
    2789                 :             :                                                           from_mode,
    2790                 :             :                                                           &actual_mode);
    2791                 :       53057 :           if (handler == CODE_FOR_nothing)
    2792                 :             :             return false;
    2793                 :             :         }
    2794                 :             :     }
    2795                 :             : 
    2796                 :             :   /* Ensure that the inputs to the handler are in the correct precison
    2797                 :             :      for the opcode.  This will be the full mode size.  */
    2798                 :       10202 :   actual_precision = GET_MODE_PRECISION (actual_mode);
    2799                 :       10202 :   if (2 * actual_precision > TYPE_PRECISION (type))
    2800                 :             :     return false;
    2801                 :       10202 :   if (actual_precision != TYPE_PRECISION (type1)
    2802                 :       10202 :       || from_unsigned1 != TYPE_UNSIGNED (type1))
    2803                 :           6 :     type1 = build_nonstandard_integer_type (actual_precision, from_unsigned1);
    2804                 :       10202 :   if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
    2805                 :             :     {
    2806                 :        9482 :       if (TREE_CODE (rhs1) == INTEGER_CST)
    2807                 :           0 :         rhs1 = fold_convert (type1, rhs1);
    2808                 :             :       else
    2809                 :        9482 :         rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
    2810                 :             :     }
    2811                 :       10202 :   if (actual_precision != TYPE_PRECISION (type2)
    2812                 :       10202 :       || from_unsigned2 != TYPE_UNSIGNED (type2))
    2813                 :           6 :     type2 = build_nonstandard_integer_type (actual_precision, from_unsigned2);
    2814                 :       10202 :   if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
    2815                 :             :     {
    2816                 :        9672 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    2817                 :        2176 :         rhs2 = fold_convert (type2, rhs2);
    2818                 :             :       else
    2819                 :        7496 :         rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
    2820                 :             :     }
    2821                 :             : 
    2822                 :       10202 :   gimple_assign_set_rhs1 (stmt, rhs1);
    2823                 :       10202 :   gimple_assign_set_rhs2 (stmt, rhs2);
    2824                 :       10202 :   gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
    2825                 :       10202 :   update_stmt (stmt);
    2826                 :       10202 :   widen_mul_stats.widen_mults_inserted++;
    2827                 :       10202 :   return true;
    2828                 :             : }
    2829                 :             : 
    2830                 :             : /* Process a single gimple statement STMT, which is found at the
    2831                 :             :    iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
    2832                 :             :    rhs (given by CODE), and try to convert it into a
    2833                 :             :    WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR.  The return value
    2834                 :             :    is true iff we converted the statement.  */
    2835                 :             : 
    2836                 :             : static bool
    2837                 :     2380909 : convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
    2838                 :             :                             enum tree_code code)
    2839                 :             : {
    2840                 :     2380909 :   gimple *rhs1_stmt = NULL, *rhs2_stmt = NULL;
    2841                 :     2380909 :   gimple *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
    2842                 :     2380909 :   tree type, type1, type2, optype;
    2843                 :     2380909 :   tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
    2844                 :     2380909 :   enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
    2845                 :     2380909 :   optab this_optab;
    2846                 :     2380909 :   enum tree_code wmult_code;
    2847                 :     2380909 :   enum insn_code handler;
    2848                 :     2380909 :   scalar_mode to_mode, from_mode, actual_mode;
    2849                 :     2380909 :   location_t loc = gimple_location (stmt);
    2850                 :     2380909 :   int actual_precision;
    2851                 :     2380909 :   bool from_unsigned1, from_unsigned2;
    2852                 :             : 
    2853                 :     2380909 :   lhs = gimple_assign_lhs (stmt);
    2854                 :     2380909 :   type = TREE_TYPE (lhs);
    2855                 :     2380909 :   if ((TREE_CODE (type) != INTEGER_TYPE
    2856                 :      391420 :        && TREE_CODE (type) != FIXED_POINT_TYPE)
    2857                 :     2380909 :       || !type_has_mode_precision_p (type))
    2858                 :      392818 :     return false;
    2859                 :             : 
    2860                 :     1988091 :   if (code == MINUS_EXPR)
    2861                 :             :     wmult_code = WIDEN_MULT_MINUS_EXPR;
    2862                 :             :   else
    2863                 :     1772749 :     wmult_code = WIDEN_MULT_PLUS_EXPR;
    2864                 :             : 
    2865                 :     1988091 :   rhs1 = gimple_assign_rhs1 (stmt);
    2866                 :     1988091 :   rhs2 = gimple_assign_rhs2 (stmt);
    2867                 :             : 
    2868                 :     1988091 :   if (TREE_CODE (rhs1) == SSA_NAME)
    2869                 :             :     {
    2870                 :     1958973 :       rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
    2871                 :     1958973 :       if (is_gimple_assign (rhs1_stmt))
    2872                 :     1144866 :         rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
    2873                 :             :     }
    2874                 :             : 
    2875                 :     1988091 :   if (TREE_CODE (rhs2) == SSA_NAME)
    2876                 :             :     {
    2877                 :      721682 :       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
    2878                 :      721682 :       if (is_gimple_assign (rhs2_stmt))
    2879                 :      550145 :         rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
    2880                 :             :     }
    2881                 :             : 
    2882                 :             :   /* Allow for one conversion statement between the multiply
    2883                 :             :      and addition/subtraction statement.  If there are more than
    2884                 :             :      one conversions then we assume they would invalidate this
    2885                 :             :      transformation.  If that's not the case then they should have
    2886                 :             :      been folded before now.  */
    2887                 :     1988091 :   if (CONVERT_EXPR_CODE_P (rhs1_code))
    2888                 :             :     {
    2889                 :      375289 :       conv1_stmt = rhs1_stmt;
    2890                 :      375289 :       rhs1 = gimple_assign_rhs1 (rhs1_stmt);
    2891                 :      375289 :       if (TREE_CODE (rhs1) == SSA_NAME)
    2892                 :             :         {
    2893                 :      315875 :           rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
    2894                 :      315875 :           if (is_gimple_assign (rhs1_stmt))
    2895                 :      178246 :             rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
    2896                 :             :         }
    2897                 :             :       else
    2898                 :             :         return false;
    2899                 :             :     }
    2900                 :     1928677 :   if (CONVERT_EXPR_CODE_P (rhs2_code))
    2901                 :             :     {
    2902                 :      167723 :       conv2_stmt = rhs2_stmt;
    2903                 :      167723 :       rhs2 = gimple_assign_rhs1 (rhs2_stmt);
    2904                 :      167723 :       if (TREE_CODE (rhs2) == SSA_NAME)
    2905                 :             :         {
    2906                 :      157596 :           rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
    2907                 :      157596 :           if (is_gimple_assign (rhs2_stmt))
    2908                 :       98829 :             rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
    2909                 :             :         }
    2910                 :             :       else
    2911                 :             :         return false;
    2912                 :             :     }
    2913                 :             : 
    2914                 :             :   /* If code is WIDEN_MULT_EXPR then it would seem unnecessary to call
    2915                 :             :      is_widening_mult_p, but we still need the rhs returns.
    2916                 :             : 
    2917                 :             :      It might also appear that it would be sufficient to use the existing
    2918                 :             :      operands of the widening multiply, but that would limit the choice of
    2919                 :             :      multiply-and-accumulate instructions.
    2920                 :             : 
    2921                 :             :      If the widened-multiplication result has more than one uses, it is
    2922                 :             :      probably wiser not to do the conversion.  Also restrict this operation
    2923                 :             :      to single basic block to avoid moving the multiply to a different block
    2924                 :             :      with a higher execution frequency.  */
    2925                 :     1918550 :   if (code == PLUS_EXPR
    2926                 :     1707659 :       && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
    2927                 :             :     {
    2928                 :      118465 :       if (!has_single_use (rhs1)
    2929                 :       71693 :           || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
    2930                 :      182152 :           || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
    2931                 :             :                                   &type2, &mult_rhs2))
    2932                 :       98528 :         return false;
    2933                 :             :       add_rhs = rhs2;
    2934                 :             :       conv_stmt = conv1_stmt;
    2935                 :             :     }
    2936                 :     1800085 :   else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
    2937                 :             :     {
    2938                 :      104944 :       if (!has_single_use (rhs2)
    2939                 :       72244 :           || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
    2940                 :      169267 :           || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
    2941                 :             :                                   &type2, &mult_rhs2))
    2942                 :       90836 :         return false;
    2943                 :             :       add_rhs = rhs1;
    2944                 :             :       conv_stmt = conv2_stmt;
    2945                 :             :     }
    2946                 :             :   else
    2947                 :             :     return false;
    2948                 :             : 
    2949                 :       34045 :   to_mode = SCALAR_TYPE_MODE (type);
    2950                 :       34045 :   from_mode = SCALAR_TYPE_MODE (type1);
    2951                 :       34045 :   if (to_mode == from_mode)
    2952                 :             :     return false;
    2953                 :             : 
    2954                 :       34042 :   from_unsigned1 = TYPE_UNSIGNED (type1);
    2955                 :       34042 :   from_unsigned2 = TYPE_UNSIGNED (type2);
    2956                 :       34042 :   optype = type1;
    2957                 :             : 
    2958                 :             :   /* There's no such thing as a mixed sign madd yet, so use a wider mode.  */
    2959                 :       34042 :   if (from_unsigned1 != from_unsigned2)
    2960                 :             :     {
    2961                 :         906 :       if (!INTEGRAL_TYPE_P (type))
    2962                 :             :         return false;
    2963                 :             :       /* We can use a signed multiply with unsigned types as long as
    2964                 :             :          there is a wider mode to use, or it is the smaller of the two
    2965                 :             :          types that is unsigned.  Note that type1 >= type2, always.  */
    2966                 :         906 :       if ((from_unsigned1
    2967                 :          52 :            && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
    2968                 :         906 :           || (from_unsigned2
    2969                 :         854 :               && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
    2970                 :             :         {
    2971                 :        1776 :           if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
    2972                 :        1812 :               || GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
    2973                 :         870 :             return false;
    2974                 :             :         }
    2975                 :             : 
    2976                 :          36 :       from_unsigned1 = from_unsigned2 = false;
    2977                 :          36 :       optype = build_nonstandard_integer_type (GET_MODE_PRECISION (from_mode),
    2978                 :             :                                                false);
    2979                 :             :     }
    2980                 :             : 
    2981                 :             :   /* If there was a conversion between the multiply and addition
    2982                 :             :      then we need to make sure it fits a multiply-and-accumulate.
    2983                 :             :      The should be a single mode change which does not change the
    2984                 :             :      value.  */
    2985                 :       33172 :   if (conv_stmt)
    2986                 :             :     {
    2987                 :             :       /* We use the original, unmodified data types for this.  */
    2988                 :         743 :       tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
    2989                 :         743 :       tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
    2990                 :         743 :       int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
    2991                 :         743 :       bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
    2992                 :             : 
    2993                 :         743 :       if (TYPE_PRECISION (from_type) > TYPE_PRECISION (to_type))
    2994                 :             :         {
    2995                 :             :           /* Conversion is a truncate.  */
    2996                 :           0 :           if (TYPE_PRECISION (to_type) < data_size)
    2997                 :             :             return false;
    2998                 :             :         }
    2999                 :         743 :       else if (TYPE_PRECISION (from_type) < TYPE_PRECISION (to_type))
    3000                 :             :         {
    3001                 :             :           /* Conversion is an extend.  Check it's the right sort.  */
    3002                 :         396 :           if (TYPE_UNSIGNED (from_type) != is_unsigned
    3003                 :         396 :               && !(is_unsigned && TYPE_PRECISION (from_type) > data_size))
    3004                 :             :             return false;
    3005                 :             :         }
    3006                 :             :       /* else convert is a no-op for our purposes.  */
    3007                 :             :     }
    3008                 :             : 
    3009                 :             :   /* Verify that the machine can perform a widening multiply
    3010                 :             :      accumulate in this mode/signedness combination, otherwise
    3011                 :             :      this transformation is likely to pessimize code.  */
    3012                 :       32833 :   this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
    3013                 :       32833 :   handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
    3014                 :             :                                                   from_mode, &actual_mode);
    3015                 :             : 
    3016                 :       32833 :   if (handler == CODE_FOR_nothing)
    3017                 :             :     return false;
    3018                 :             : 
    3019                 :             :   /* Ensure that the inputs to the handler are in the correct precison
    3020                 :             :      for the opcode.  This will be the full mode size.  */
    3021                 :           0 :   actual_precision = GET_MODE_PRECISION (actual_mode);
    3022                 :           0 :   if (actual_precision != TYPE_PRECISION (type1)
    3023                 :           0 :       || from_unsigned1 != TYPE_UNSIGNED (type1))
    3024                 :           0 :     type1 = build_nonstandard_integer_type (actual_precision, from_unsigned1);
    3025                 :           0 :   if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
    3026                 :             :     {
    3027                 :           0 :       if (TREE_CODE (mult_rhs1) == INTEGER_CST)
    3028                 :           0 :         mult_rhs1 = fold_convert (type1, mult_rhs1);
    3029                 :             :       else
    3030                 :           0 :         mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
    3031                 :             :     }
    3032                 :           0 :   if (actual_precision != TYPE_PRECISION (type2)
    3033                 :           0 :       || from_unsigned2 != TYPE_UNSIGNED (type2))
    3034                 :           0 :     type2 = build_nonstandard_integer_type (actual_precision, from_unsigned2);
    3035                 :           0 :   if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
    3036                 :             :     {
    3037                 :           0 :       if (TREE_CODE (mult_rhs2) == INTEGER_CST)
    3038                 :           0 :         mult_rhs2 = fold_convert (type2, mult_rhs2);
    3039                 :             :       else
    3040                 :           0 :         mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
    3041                 :             :     }
    3042                 :             : 
    3043                 :           0 :   if (!useless_type_conversion_p (type, TREE_TYPE (add_rhs)))
    3044                 :           0 :     add_rhs = build_and_insert_cast (gsi, loc, type, add_rhs);
    3045                 :             : 
    3046                 :           0 :   gimple_assign_set_rhs_with_ops (gsi, wmult_code, mult_rhs1, mult_rhs2,
    3047                 :             :                                   add_rhs);
    3048                 :           0 :   update_stmt (gsi_stmt (*gsi));
    3049                 :           0 :   widen_mul_stats.maccs_inserted++;
    3050                 :           0 :   return true;
    3051                 :             : }
    3052                 :             : 
    3053                 :             : /* Given a result MUL_RESULT which is a result of a multiplication of OP1 and
    3054                 :             :    OP2 and which we know is used in statements that can be, together with the
    3055                 :             :    multiplication, converted to FMAs, perform the transformation.  */
    3056                 :             : 
    3057                 :             : static void
    3058                 :       18254 : convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
    3059                 :             : {
    3060                 :       18254 :   tree type = TREE_TYPE (mul_result);
    3061                 :       18254 :   gimple *use_stmt;
    3062                 :       18254 :   imm_use_iterator imm_iter;
    3063                 :       18254 :   gcall *fma_stmt;
    3064                 :             : 
    3065                 :       36579 :   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result)
    3066                 :             :     {
    3067                 :       18325 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    3068                 :       18325 :       tree addop, mulop1 = op1, result = mul_result;
    3069                 :       18325 :       bool negate_p = false;
    3070                 :       18325 :       gimple_seq seq = NULL;
    3071                 :             : 
    3072                 :       18325 :       if (is_gimple_debug (use_stmt))
    3073                 :           0 :         continue;
    3074                 :             : 
    3075                 :       18325 :       if (is_gimple_assign (use_stmt)
    3076                 :       18325 :           && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
    3077                 :             :         {
    3078                 :         700 :           result = gimple_assign_lhs (use_stmt);
    3079                 :         700 :           use_operand_p use_p;
    3080                 :         700 :           gimple *neguse_stmt;
    3081                 :         700 :           single_imm_use (gimple_assign_lhs (use_stmt), &use_p, &neguse_stmt);
    3082                 :         700 :           gsi_remove (&gsi, true);
    3083                 :         700 :           release_defs (use_stmt);
    3084                 :             : 
    3085                 :         700 :           use_stmt = neguse_stmt;
    3086                 :         700 :           gsi = gsi_for_stmt (use_stmt);
    3087                 :         700 :           negate_p = true;
    3088                 :             :         }
    3089                 :             : 
    3090                 :       18325 :       tree cond, else_value, ops[3], len, bias;
    3091                 :       18325 :       tree_code code;
    3092                 :       18325 :       if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code,
    3093                 :             :                                               ops, &else_value,
    3094                 :             :                                               &len, &bias))
    3095                 :           0 :         gcc_unreachable ();
    3096                 :       18325 :       addop = ops[0] == result ? ops[1] : ops[0];
    3097                 :             : 
    3098                 :       18325 :       if (code == MINUS_EXPR)
    3099                 :             :         {
    3100                 :        6204 :           if (ops[0] == result)
    3101                 :             :             /* a * b - c -> a * b + (-c)  */
    3102                 :        2896 :             addop = gimple_build (&seq, NEGATE_EXPR, type, addop);
    3103                 :             :           else
    3104                 :             :             /* a - b * c -> (-b) * c + a */
    3105                 :        3308 :             negate_p = !negate_p;
    3106                 :             :         }
    3107                 :             : 
    3108                 :       18325 :       if (negate_p)
    3109                 :        4008 :         mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1);
    3110                 :             : 
    3111                 :       18325 :       if (seq)
    3112                 :        6199 :         gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    3113                 :             : 
    3114                 :       18325 :       if (len)
    3115                 :           0 :         fma_stmt
    3116                 :           0 :           = gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2,
    3117                 :             :                                         addop, else_value, len, bias);
    3118                 :       18325 :       else if (cond)
    3119                 :          89 :         fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
    3120                 :             :                                                op2, addop, else_value);
    3121                 :             :       else
    3122                 :       18236 :         fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
    3123                 :       18325 :       gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
    3124                 :       18325 :       gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
    3125                 :             :                                                                    use_stmt));
    3126                 :       18325 :       gsi_replace (&gsi, fma_stmt, true);
    3127                 :             :       /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
    3128                 :             :          regardless of where the negation occurs.  */
    3129                 :       18325 :       gimple *orig_stmt = gsi_stmt (gsi);
    3130                 :       18325 :       if (fold_stmt (&gsi, follow_all_ssa_edges))
    3131                 :             :         {
    3132                 :        6247 :           if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
    3133                 :           0 :             gcc_unreachable ();
    3134                 :        6247 :           update_stmt (gsi_stmt (gsi));
    3135                 :             :         }
    3136                 :             : 
    3137                 :       18325 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3138                 :             :         {
    3139                 :           3 :           fprintf (dump_file, "Generated FMA ");
    3140                 :           3 :           print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
    3141                 :           3 :           fprintf (dump_file, "\n");
    3142                 :             :         }
    3143                 :             : 
    3144                 :             :       /* If the FMA result is negated in a single use, fold the negation
    3145                 :             :          too.  */
    3146                 :       18325 :       orig_stmt = gsi_stmt (gsi);
    3147                 :       18325 :       use_operand_p use_p;
    3148                 :       18325 :       gimple *neg_stmt;
    3149                 :       18325 :       if (is_gimple_call (orig_stmt)
    3150                 :       18325 :           && gimple_call_internal_p (orig_stmt)
    3151                 :       18325 :           && gimple_call_lhs (orig_stmt)
    3152                 :       18325 :           && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME
    3153                 :       18325 :           && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt)
    3154                 :       13686 :           && is_gimple_assign (neg_stmt)
    3155                 :       10689 :           && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR
    3156                 :       19678 :           && !stmt_could_throw_p (cfun, neg_stmt))
    3157                 :             :         {
    3158                 :        1353 :           gsi = gsi_for_stmt (neg_stmt);
    3159                 :        1353 :           if (fold_stmt (&gsi, follow_all_ssa_edges))
    3160                 :             :             {
    3161                 :        1353 :               if (maybe_clean_or_replace_eh_stmt (neg_stmt, gsi_stmt (gsi)))
    3162                 :           0 :                 gcc_unreachable ();
    3163                 :        1353 :               update_stmt (gsi_stmt (gsi));
    3164                 :        1353 :               if (dump_file && (dump_flags & TDF_DETAILS))
    3165                 :             :                 {
    3166                 :           0 :                   fprintf (dump_file, "Folded FMA negation ");
    3167                 :           0 :                   print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
    3168                 :           0 :                   fprintf (dump_file, "\n");
    3169                 :             :                 }
    3170                 :             :             }
    3171                 :             :         }
    3172                 :             : 
    3173                 :       18325 :       widen_mul_stats.fmas_inserted++;
    3174                 :       18254 :     }
    3175                 :       18254 : }
    3176                 :             : 
    3177                 :             : /* Data necessary to perform the actual transformation from a multiplication
    3178                 :             :    and an addition to an FMA after decision is taken it should be done and to
    3179                 :             :    then delete the multiplication statement from the function IL.  */
    3180                 :             : 
    3181                 :             : struct fma_transformation_info
    3182                 :             : {
    3183                 :             :   gimple *mul_stmt;
    3184                 :             :   tree mul_result;
    3185                 :             :   tree op1;
    3186                 :             :   tree op2;
    3187                 :             : };
    3188                 :             : 
    3189                 :             : /* Structure containing the current state of FMA deferring, i.e. whether we are
    3190                 :             :    deferring, whether to continue deferring, and all data necessary to come
    3191                 :             :    back and perform all deferred transformations.  */
    3192                 :             : 
    3193                 :     9836340 : class fma_deferring_state
    3194                 :             : {
    3195                 :             : public:
    3196                 :             :   /* Class constructor.  Pass true as PERFORM_DEFERRING in order to actually
    3197                 :             :      do any deferring.  */
    3198                 :             : 
    3199                 :     9836340 :   fma_deferring_state (bool perform_deferring)
    3200                 :     9836340 :     : m_candidates (), m_mul_result_set (), m_initial_phi (NULL),
    3201                 :     9836340 :       m_last_result (NULL_TREE), m_deferring_p (perform_deferring) {}
    3202                 :             : 
    3203                 :             :   /* List of FMA candidates for which we the transformation has been determined
    3204                 :             :      possible but we at this point in BB analysis we do not consider them
    3205                 :             :      beneficial.  */
    3206                 :             :   auto_vec<fma_transformation_info, 8> m_candidates;
    3207                 :             : 
    3208                 :             :   /* Set of results of multiplication that are part of an already deferred FMA
    3209                 :             :      candidates.  */
    3210                 :             :   hash_set<tree> m_mul_result_set;
    3211                 :             : 
    3212                 :             :   /* The PHI that supposedly feeds back result of a FMA to another over loop
    3213                 :             :      boundary.  */
    3214                 :             :   gphi *m_initial_phi;
    3215                 :             : 
    3216                 :             :   /* Result of the last produced FMA candidate or NULL if there has not been
    3217                 :             :      one.  */
    3218                 :             :   tree m_last_result;
    3219                 :             : 
    3220                 :             :   /* If true, deferring might still be profitable.  If false, transform all
    3221                 :             :      candidates and no longer defer.  */
    3222                 :             :   bool m_deferring_p;
    3223                 :             : };
    3224                 :             : 
    3225                 :             : /* Transform all deferred FMA candidates and mark STATE as no longer
    3226                 :             :    deferring.  */
    3227                 :             : 
    3228                 :             : static void
    3229                 :     3484095 : cancel_fma_deferring (fma_deferring_state *state)
    3230                 :             : {
    3231                 :     3484095 :   if (!state->m_deferring_p)
    3232                 :             :     return;
    3233                 :             : 
    3234                 :     2524580 :   for (unsigned i = 0; i < state->m_candidates.length (); i++)
    3235                 :             :     {
    3236                 :         946 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3237                 :           0 :         fprintf (dump_file, "Generating deferred FMA\n");
    3238                 :             : 
    3239                 :         946 :       const fma_transformation_info &fti = state->m_candidates[i];
    3240                 :         946 :       convert_mult_to_fma_1 (fti.mul_result, fti.op1, fti.op2);
    3241                 :             : 
    3242                 :         946 :       gimple_stmt_iterator gsi = gsi_for_stmt (fti.mul_stmt);
    3243                 :         946 :       gsi_remove (&gsi, true);
    3244                 :         946 :       release_defs (fti.mul_stmt);
    3245                 :             :     }
    3246                 :     2523634 :   state->m_deferring_p = false;
    3247                 :             : }
    3248                 :             : 
    3249                 :             : /* If OP is an SSA name defined by a PHI node, return the PHI statement.
    3250                 :             :    Otherwise return NULL.  */
    3251                 :             : 
    3252                 :             : static gphi *
    3253                 :        4781 : result_of_phi (tree op)
    3254                 :             : {
    3255                 :           0 :   if (TREE_CODE (op) != SSA_NAME)
    3256                 :             :     return NULL;
    3257                 :             : 
    3258                 :        4737 :   return dyn_cast <gphi *> (SSA_NAME_DEF_STMT (op));
    3259                 :             : }
    3260                 :             : 
    3261                 :             : /* After processing statements of a BB and recording STATE, return true if the
    3262                 :             :    initial phi is fed by the last FMA candidate result ore one such result from
    3263                 :             :    previously processed BBs marked in LAST_RESULT_SET.  */
    3264                 :             : 
    3265                 :             : static bool
    3266                 :         293 : last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
    3267                 :             :                                       hash_set<tree> *last_result_set)
    3268                 :             : {
    3269                 :         293 :   ssa_op_iter iter;
    3270                 :         293 :   use_operand_p use;
    3271                 :         629 :   FOR_EACH_PHI_ARG (use, state->m_initial_phi, iter, SSA_OP_USE)
    3272                 :             :     {
    3273                 :         461 :       tree t = USE_FROM_PTR (use);
    3274                 :         461 :       if (t == state->m_last_result
    3275                 :         461 :           || last_result_set->contains (t))
    3276                 :         125 :         return true;
    3277                 :             :     }
    3278                 :             : 
    3279                 :             :   return false;
    3280                 :             : }
    3281                 :             : 
    3282                 :             : /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
    3283                 :             :    with uses in additions and subtractions to form fused multiply-add
    3284                 :             :    operations.  Returns true if successful and MUL_STMT should be removed.
    3285                 :             :    If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
    3286                 :             :    on MUL_COND, otherwise it is unconditional.
    3287                 :             : 
    3288                 :             :    If STATE indicates that we are deferring FMA transformation, that means
    3289                 :             :    that we do not produce FMAs for basic blocks which look like:
    3290                 :             : 
    3291                 :             :     <bb 6>
    3292                 :             :     # accumulator_111 = PHI <0.0(5), accumulator_66(6)>
    3293                 :             :     _65 = _14 * _16;
    3294                 :             :     accumulator_66 = _65 + accumulator_111;
    3295                 :             : 
    3296                 :             :   or its unrolled version, i.e. with several FMA candidates that feed result
    3297                 :             :   of one into the addend of another.  Instead, we add them to a list in STATE
    3298                 :             :   and if we later discover an FMA candidate that is not part of such a chain,
    3299                 :             :   we go back and perform all deferred past candidates.  */
    3300                 :             : 
    3301                 :             : static bool
    3302                 :      652815 : convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
    3303                 :             :                      fma_deferring_state *state, tree mul_cond = NULL_TREE,
    3304                 :             :                      tree mul_len = NULL_TREE, tree mul_bias = NULL_TREE)
    3305                 :             : {
    3306                 :      652815 :   tree mul_result = gimple_get_lhs (mul_stmt);
    3307                 :             :   /* If there isn't a LHS then this can't be an FMA.  There can be no LHS
    3308                 :             :      if the statement was left just for the side-effects.  */
    3309                 :      652815 :   if (!mul_result)
    3310                 :             :     return false;
    3311                 :      652815 :   tree type = TREE_TYPE (mul_result);
    3312                 :      652815 :   gimple *use_stmt, *neguse_stmt;
    3313                 :      652815 :   use_operand_p use_p;
    3314                 :      652815 :   imm_use_iterator imm_iter;
    3315                 :             : 
    3316                 :      551691 :   if (FLOAT_TYPE_P (type)
    3317                 :      673141 :       && flag_fp_contract_mode != FP_CONTRACT_FAST)
    3318                 :             :     return false;
    3319                 :             : 
    3320                 :             :   /* We don't want to do bitfield reduction ops.  */
    3321                 :      647678 :   if (INTEGRAL_TYPE_P (type)
    3322                 :      647678 :       && (!type_has_mode_precision_p (type) || TYPE_OVERFLOW_TRAPS (type)))
    3323                 :             :     return false;
    3324                 :             : 
    3325                 :             :   /* If the target doesn't support it, don't generate it.  We assume that
    3326                 :             :      if fma isn't available then fms, fnma or fnms are not either.  */
    3327                 :      647508 :   optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt));
    3328                 :      647508 :   if (!direct_internal_fn_supported_p (IFN_FMA, type, opt_type))
    3329                 :             :     return false;
    3330                 :             : 
    3331                 :             :   /* If the multiplication has zero uses, it is kept around probably because
    3332                 :             :      of -fnon-call-exceptions.  Don't optimize it away in that case,
    3333                 :             :      it is DCE job.  */
    3334                 :       23072 :   if (has_zero_uses (mul_result))
    3335                 :             :     return false;
    3336                 :             : 
    3337                 :       23072 :   bool check_defer
    3338                 :       23072 :     = (state->m_deferring_p
    3339                 :       23072 :        && maybe_le (tree_to_poly_int64 (TYPE_SIZE (type)),
    3340                 :       23072 :                     param_avoid_fma_max_bits));
    3341                 :       23072 :   bool defer = check_defer;
    3342                 :       23072 :   bool seen_negate_p = false;
    3343                 :             : 
    3344                 :             :   /* There is no numerical difference between fused and unfused integer FMAs,
    3345                 :             :      and the assumption below that FMA is as cheap as addition is unlikely
    3346                 :             :      to be true, especially if the multiplication occurs multiple times on
    3347                 :             :      the same chain.  E.g., for something like:
    3348                 :             : 
    3349                 :             :          (((a * b) + c) >> 1) + (a * b)
    3350                 :             : 
    3351                 :             :      we do not want to duplicate the a * b into two additions, not least
    3352                 :             :      because the result is not a natural FMA chain.  */
    3353                 :       23072 :   if (ANY_INTEGRAL_TYPE_P (type)
    3354                 :       23072 :       && !has_single_use (mul_result))
    3355                 :             :     return false;
    3356                 :             : 
    3357                 :       23072 :   if (!dbg_cnt (form_fma))
    3358                 :             :     return false;
    3359                 :             : 
    3360                 :             :   /* Make sure that the multiplication statement becomes dead after
    3361                 :             :      the transformation, thus that all uses are transformed to FMAs.
    3362                 :             :      This means we assume that an FMA operation has the same cost
    3363                 :             :      as an addition.  */
    3364                 :       42370 :   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
    3365                 :             :     {
    3366                 :       23991 :       tree result = mul_result;
    3367                 :       23991 :       bool negate_p = false;
    3368                 :             : 
    3369                 :       23991 :       use_stmt = USE_STMT (use_p);
    3370                 :             : 
    3371                 :       23991 :       if (is_gimple_debug (use_stmt))
    3372                 :         390 :         continue;
    3373                 :             : 
    3374                 :             :       /* For now restrict this operations to single basic blocks.  In theory
    3375                 :             :          we would want to support sinking the multiplication in
    3376                 :             :          m = a*b;
    3377                 :             :          if ()
    3378                 :             :            ma = m + c;
    3379                 :             :          else
    3380                 :             :            d = m;
    3381                 :             :          to form a fma in the then block and sink the multiplication to the
    3382                 :             :          else block.  */
    3383                 :       23601 :       if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
    3384                 :        4693 :         return false;
    3385                 :             : 
    3386                 :             :       /* A negate on the multiplication leads to FNMA.  */
    3387                 :       22730 :       if (is_gimple_assign (use_stmt)
    3388                 :       22730 :           && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
    3389                 :             :         {
    3390                 :         706 :           ssa_op_iter iter;
    3391                 :         706 :           use_operand_p usep;
    3392                 :             : 
    3393                 :             :           /* If (due to earlier missed optimizations) we have two
    3394                 :             :              negates of the same value, treat them as equivalent
    3395                 :             :              to a single negate with multiple uses.  */
    3396                 :         706 :           if (seen_negate_p)
    3397                 :           0 :             return false;
    3398                 :             : 
    3399                 :         706 :           result = gimple_assign_lhs (use_stmt);
    3400                 :             : 
    3401                 :             :           /* Make sure the negate statement becomes dead with this
    3402                 :             :              single transformation.  */
    3403                 :         706 :           if (!single_imm_use (gimple_assign_lhs (use_stmt),
    3404                 :             :                                &use_p, &neguse_stmt))
    3405                 :             :             return false;
    3406                 :             : 
    3407                 :             :           /* Make sure the multiplication isn't also used on that stmt.  */
    3408                 :        2836 :           FOR_EACH_PHI_OR_STMT_USE (usep, neguse_stmt, iter, SSA_OP_USE)
    3409                 :        1424 :             if (USE_FROM_PTR (usep) == mul_result)
    3410                 :             :               return false;
    3411                 :             : 
    3412                 :             :           /* Re-validate.  */
    3413                 :         706 :           use_stmt = neguse_stmt;
    3414                 :         706 :           if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
    3415                 :             :             return false;
    3416                 :             : 
    3417                 :         706 :           negate_p = seen_negate_p = true;
    3418                 :             :         }
    3419                 :             : 
    3420                 :       22730 :       tree cond, else_value, ops[3], len, bias;
    3421                 :       22730 :       tree_code code;
    3422                 :       22730 :       if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
    3423                 :             :                                               &else_value, &len, &bias))
    3424                 :             :         return false;
    3425                 :             : 
    3426                 :       20802 :       switch (code)
    3427                 :             :         {
    3428                 :        6210 :         case MINUS_EXPR:
    3429                 :        6210 :           if (ops[1] == result)
    3430                 :        3308 :             negate_p = !negate_p;
    3431                 :             :           break;
    3432                 :             :         case PLUS_EXPR:
    3433                 :             :           break;
    3434                 :             :         default:
    3435                 :             :           /* FMA can only be formed from PLUS and MINUS.  */
    3436                 :             :           return false;
    3437                 :             :         }
    3438                 :             : 
    3439                 :       18925 :       if (len)
    3440                 :             :         {
    3441                 :             :           /* For COND_LEN_* operations, we may have dummpy mask which is
    3442                 :             :              the all true mask.  Such TREE type may be mul_cond != cond
    3443                 :             :              but we still consider they are equal.  */
    3444                 :           0 :           if (mul_cond && cond != mul_cond
    3445                 :           0 :               && !(integer_truep (mul_cond) && integer_truep (cond)))
    3446                 :           0 :             return false;
    3447                 :             : 
    3448                 :           0 :           if (else_value == result)
    3449                 :             :             return false;
    3450                 :             : 
    3451                 :           0 :           if (!direct_internal_fn_supported_p (IFN_COND_LEN_FMA, type,
    3452                 :             :                                                opt_type))
    3453                 :             :             return false;
    3454                 :             : 
    3455                 :           0 :           if (mul_len)
    3456                 :             :             {
    3457                 :           0 :               poly_int64 mul_value, value;
    3458                 :           0 :               if (poly_int_tree_p (mul_len, &mul_value)
    3459                 :           0 :                   && poly_int_tree_p (len, &value)
    3460                 :           0 :                   && maybe_ne (mul_value, value))
    3461                 :           0 :                 return false;
    3462                 :           0 :               else if (mul_len != len)
    3463                 :             :                 return false;
    3464                 :             : 
    3465                 :           0 :               if (wi::to_widest (mul_bias) != wi::to_widest (bias))
    3466                 :             :                 return false;
    3467                 :             :             }
    3468                 :             :         }
    3469                 :             :       else
    3470                 :             :         {
    3471                 :       18925 :           if (mul_cond && cond != mul_cond)
    3472                 :             :             return false;
    3473                 :             : 
    3474                 :       18913 :           if (cond)
    3475                 :             :             {
    3476                 :          94 :               if (cond == result || else_value == result)
    3477                 :             :                 return false;
    3478                 :          89 :               if (!direct_internal_fn_supported_p (IFN_COND_FMA, type,
    3479                 :             :                                                    opt_type))
    3480                 :             :                 return false;
    3481                 :             :             }
    3482                 :             :         }
    3483                 :             : 
    3484                 :             :       /* If the subtrahend (OPS[1]) is computed by a MULT_EXPR that
    3485                 :             :          we'll visit later, we might be able to get a more profitable
    3486                 :             :          match with fnma.
    3487                 :             :          OTOH, if we don't, a negate / fma pair has likely lower latency
    3488                 :             :          that a mult / subtract pair.  */
    3489                 :       18908 :       if (code == MINUS_EXPR
    3490                 :        6204 :           && !negate_p
    3491                 :        2196 :           && ops[0] == result
    3492                 :        2196 :           && !direct_internal_fn_supported_p (IFN_FMS, type, opt_type)
    3493                 :           0 :           && direct_internal_fn_supported_p (IFN_FNMA, type, opt_type)
    3494                 :           0 :           && TREE_CODE (ops[1]) == SSA_NAME
    3495                 :       18908 :           && has_single_use (ops[1]))
    3496                 :             :         {
    3497                 :           0 :           gimple *stmt2 = SSA_NAME_DEF_STMT (ops[1]);
    3498                 :           0 :           if (is_gimple_assign (stmt2)
    3499                 :           0 :               && gimple_assign_rhs_code (stmt2) == MULT_EXPR)
    3500                 :             :             return false;
    3501                 :             :         }
    3502                 :             : 
    3503                 :             :       /* We can't handle a * b + a * b.  */
    3504                 :       18908 :       if (ops[0] == ops[1])
    3505                 :             :         return false;
    3506                 :             :       /* If deferring, make sure we are not looking at an instruction that
    3507                 :             :          wouldn't have existed if we were not.  */
    3508                 :       18908 :       if (state->m_deferring_p
    3509                 :       18908 :           && (state->m_mul_result_set.contains (ops[0])
    3510                 :        6075 :               || state->m_mul_result_set.contains (ops[1])))
    3511                 :           0 :         return false;
    3512                 :             : 
    3513                 :       18908 :       if (check_defer)
    3514                 :             :         {
    3515                 :        5927 :           tree use_lhs = gimple_get_lhs (use_stmt);
    3516                 :        5927 :           if (state->m_last_result)
    3517                 :             :             {
    3518                 :        1146 :               if (ops[1] == state->m_last_result
    3519                 :        1146 :                   || ops[0] == state->m_last_result)
    3520                 :             :                 defer = true;
    3521                 :             :               else
    3522                 :        5927 :                 defer = false;
    3523                 :             :             }
    3524                 :             :           else
    3525                 :             :             {
    3526                 :        4781 :               gcc_checking_assert (!state->m_initial_phi);
    3527                 :        4781 :               gphi *phi;
    3528                 :        4781 :               if (ops[0] == result)
    3529                 :        2996 :                 phi = result_of_phi (ops[1]);
    3530                 :             :               else
    3531                 :             :                 {
    3532                 :        1785 :                   gcc_assert (ops[1] == result);
    3533                 :        1785 :                   phi = result_of_phi (ops[0]);
    3534                 :             :                 }
    3535                 :             : 
    3536                 :             :               if (phi)
    3537                 :             :                 {
    3538                 :         891 :                   state->m_initial_phi = phi;
    3539                 :         891 :                   defer = true;
    3540                 :             :                 }
    3541                 :             :               else
    3542                 :             :                 defer = false;
    3543                 :             :             }
    3544                 :             : 
    3545                 :        5927 :           state->m_last_result = use_lhs;
    3546                 :        5927 :           check_defer = false;
    3547                 :             :         }
    3548                 :             :       else
    3549                 :             :         defer = false;
    3550                 :             : 
    3551                 :             :       /* While it is possible to validate whether or not the exact form that
    3552                 :             :          we've recognized is available in the backend, the assumption is that
    3553                 :             :          if the deferring logic above did not trigger, the transformation is
    3554                 :             :          never a loss.  For instance, suppose the target only has the plain FMA
    3555                 :             :          pattern available.  Consider a*b-c -> fma(a,b,-c): we've exchanged
    3556                 :             :          MUL+SUB for FMA+NEG, which is still two operations.  Consider
    3557                 :             :          -(a*b)-c -> fma(-a,b,-c): we still have 3 operations, but in the FMA
    3558                 :             :          form the two NEGs are independent and could be run in parallel.  */
    3559                 :             :     }
    3560                 :             : 
    3561                 :       18379 :   if (defer)
    3562                 :             :     {
    3563                 :        1071 :       fma_transformation_info fti;
    3564                 :        1071 :       fti.mul_stmt = mul_stmt;
    3565                 :        1071 :       fti.mul_result = mul_result;
    3566                 :        1071 :       fti.op1 = op1;
    3567                 :        1071 :       fti.op2 = op2;
    3568                 :        1071 :       state->m_candidates.safe_push (fti);
    3569                 :        1071 :       state->m_mul_result_set.add (mul_result);
    3570                 :             : 
    3571                 :        1071 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3572                 :             :         {
    3573                 :           0 :           fprintf (dump_file, "Deferred generating FMA for multiplication ");
    3574                 :           0 :           print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE);
    3575                 :           0 :           fprintf (dump_file, "\n");
    3576                 :             :         }
    3577                 :             : 
    3578                 :        1071 :       return false;
    3579                 :             :     }
    3580                 :             :   else
    3581                 :             :     {
    3582                 :       17308 :       if (state->m_deferring_p)
    3583                 :        4516 :         cancel_fma_deferring (state);
    3584                 :       17308 :       convert_mult_to_fma_1 (mul_result, op1, op2);
    3585                 :       17308 :       return true;
    3586                 :             :     }
    3587                 :             : }
    3588                 :             : 
    3589                 :             : 
    3590                 :             : /* Helper function of match_arith_overflow.  For MUL_OVERFLOW, if we have
    3591                 :             :    a check for non-zero like:
    3592                 :             :    _1 = x_4(D) * y_5(D);
    3593                 :             :    *res_7(D) = _1;
    3594                 :             :    if (x_4(D) != 0)
    3595                 :             :      goto <bb 3>; [50.00%]
    3596                 :             :    else
    3597                 :             :      goto <bb 4>; [50.00%]
    3598                 :             : 
    3599                 :             :    <bb 3> [local count: 536870913]:
    3600                 :             :    _2 = _1 / x_4(D);
    3601                 :             :    _9 = _2 != y_5(D);
    3602                 :             :    _10 = (int) _9;
    3603                 :             : 
    3604                 :             :    <bb 4> [local count: 1073741824]:
    3605                 :             :    # iftmp.0_3 = PHI <_10(3), 0(2)>
    3606                 :             :    then in addition to using .MUL_OVERFLOW (x_4(D), y_5(D)) we can also
    3607                 :             :    optimize the x_4(D) != 0 condition to 1.  */
    3608                 :             : 
    3609                 :             : static void
    3610                 :         144 : maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
    3611                 :             :                                gimple *div_stmt, bool *cfg_changed)
    3612                 :             : {
    3613                 :         144 :   basic_block bb = gimple_bb (cond_stmt);
    3614                 :         288 :   if (gimple_bb (div_stmt) != bb || !single_pred_p (bb))
    3615                 :          51 :     return;
    3616                 :         144 :   edge pred_edge = single_pred_edge (bb);
    3617                 :         144 :   basic_block pred_bb = pred_edge->src;
    3618                 :         144 :   if (EDGE_COUNT (pred_bb->succs) != 2)
    3619                 :             :     return;
    3620                 :         101 :   edge other_edge = EDGE_SUCC (pred_bb, EDGE_SUCC (pred_bb, 0) == pred_edge);
    3621                 :         101 :   edge other_succ_edge = NULL;
    3622                 :         101 :   if (gimple_code (cond_stmt) == GIMPLE_COND)
    3623                 :             :     {
    3624                 :          48 :       if (EDGE_COUNT (bb->succs) != 2)
    3625                 :             :         return;
    3626                 :          48 :       other_succ_edge = EDGE_SUCC (bb, 0);
    3627                 :          48 :       if (gimple_cond_code (cond_stmt) == NE_EXPR)
    3628                 :             :         {
    3629                 :          24 :           if (other_succ_edge->flags & EDGE_TRUE_VALUE)
    3630                 :          24 :             other_succ_edge = EDGE_SUCC (bb, 1);
    3631                 :             :         }
    3632                 :             :       else if (other_succ_edge->flags & EDGE_FALSE_VALUE)
    3633                 :          48 :         other_succ_edge = EDGE_SUCC (bb, 0);
    3634                 :          48 :       if (other_edge->dest != other_succ_edge->dest)
    3635                 :             :         return;
    3636                 :             :     }
    3637                 :         104 :   else if (!single_succ_p (bb) || other_edge->dest != single_succ (bb))
    3638                 :             :     return;
    3639                 :         200 :   gcond *zero_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (pred_bb));
    3640                 :         100 :   if (zero_cond == NULL
    3641                 :         100 :       || (gimple_cond_code (zero_cond)
    3642                 :         100 :           != ((pred_edge->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR))
    3643                 :         100 :       || !integer_zerop (gimple_cond_rhs (zero_cond)))
    3644                 :           0 :     return;
    3645                 :         100 :   tree zero_cond_lhs = gimple_cond_lhs (zero_cond);
    3646                 :         100 :   if (TREE_CODE (zero_cond_lhs) != SSA_NAME)
    3647                 :             :     return;
    3648                 :         100 :   if (gimple_assign_rhs2 (div_stmt) != zero_cond_lhs)
    3649                 :             :     {
    3650                 :             :       /* Allow the divisor to be result of a same precision cast
    3651                 :             :          from zero_cond_lhs.  */
    3652                 :          52 :       tree rhs2 = gimple_assign_rhs2 (div_stmt);
    3653                 :          52 :       if (TREE_CODE (rhs2) != SSA_NAME)
    3654                 :             :         return;
    3655                 :          52 :       gimple *g = SSA_NAME_DEF_STMT (rhs2);
    3656                 :          52 :       if (!gimple_assign_cast_p (g)
    3657                 :          52 :           || gimple_assign_rhs1 (g) != gimple_cond_lhs (zero_cond)
    3658                 :          52 :           || !INTEGRAL_TYPE_P (TREE_TYPE (zero_cond_lhs))
    3659                 :         104 :           || (TYPE_PRECISION (TREE_TYPE (zero_cond_lhs))
    3660                 :          52 :               != TYPE_PRECISION (TREE_TYPE (rhs2))))
    3661                 :             :         return;
    3662                 :             :     }
    3663                 :         100 :   gimple_stmt_iterator gsi = gsi_after_labels (bb);
    3664                 :         100 :   mul_stmts.quick_push (div_stmt);
    3665                 :         100 :   if (is_gimple_debug (gsi_stmt (gsi)))
    3666                 :           0 :     gsi_next_nondebug (&gsi);
    3667                 :             :   unsigned cast_count = 0;
    3668                 :         629 :   while (gsi_stmt (gsi) != cond_stmt)
    3669                 :             :     {
    3670                 :             :       /* If original mul_stmt has a single use, allow it in the same bb,
    3671                 :             :          we are looking then just at __builtin_mul_overflow_p.
    3672                 :             :          Though, in that case the original mul_stmt will be replaced
    3673                 :             :          by .MUL_OVERFLOW, REALPART_EXPR and IMAGPART_EXPR stmts.  */
    3674                 :             :       gimple *mul_stmt;
    3675                 :             :       unsigned int i;
    3676                 :        2259 :       bool ok = false;
    3677                 :        2259 :       FOR_EACH_VEC_ELT (mul_stmts, i, mul_stmt)
    3678                 :             :         {
    3679                 :        2113 :           if (gsi_stmt (gsi) == mul_stmt)
    3680                 :             :             {
    3681                 :             :               ok = true;
    3682                 :             :               break;
    3683                 :             :             }
    3684                 :             :         }
    3685                 :         529 :       if (!ok && gimple_assign_cast_p (gsi_stmt (gsi)) && ++cast_count < 4)
    3686                 :             :         ok = true;
    3687                 :         383 :       if (!ok)
    3688                 :          51 :         return;
    3689                 :         529 :       gsi_next_nondebug (&gsi);
    3690                 :             :     }
    3691                 :         100 :   if (gimple_code (cond_stmt) == GIMPLE_COND)
    3692                 :             :     {
    3693                 :          47 :       basic_block succ_bb = other_edge->dest;
    3694                 :          75 :       for (gphi_iterator gpi = gsi_start_phis (succ_bb); !gsi_end_p (gpi);
    3695                 :          28 :            gsi_next (&gpi))
    3696                 :             :         {
    3697                 :          35 :           gphi *phi = gpi.phi ();
    3698                 :          35 :           tree v1 = gimple_phi_arg_def (phi, other_edge->dest_idx);
    3699                 :          35 :           tree v2 = gimple_phi_arg_def (phi, other_succ_edge->dest_idx);
    3700                 :          35 :           if (!operand_equal_p (v1, v2, 0))
    3701                 :           7 :             return;
    3702                 :             :         }
    3703                 :             :     }
    3704                 :             :   else
    3705                 :             :     {
    3706                 :          53 :       tree lhs = gimple_assign_lhs (cond_stmt);
    3707                 :          53 :       if (!lhs || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
    3708                 :             :         return;
    3709                 :          53 :       gsi_next_nondebug (&gsi);
    3710                 :          53 :       if (!gsi_end_p (gsi))
    3711                 :             :         {
    3712                 :          53 :           if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
    3713                 :             :             return;
    3714                 :          53 :           gimple *cast_stmt = gsi_stmt (gsi);
    3715                 :          53 :           if (!gimple_assign_cast_p (cast_stmt))
    3716                 :             :             return;
    3717                 :          53 :           tree new_lhs = gimple_assign_lhs (cast_stmt);
    3718                 :          53 :           gsi_next_nondebug (&gsi);
    3719                 :          53 :           if (!gsi_end_p (gsi)
    3720                 :          53 :               || !new_lhs
    3721                 :          53 :               || !INTEGRAL_TYPE_P (TREE_TYPE (new_lhs))
    3722                 :         106 :               || TYPE_PRECISION (TREE_TYPE (new_lhs)) <= 1)
    3723                 :             :             return;
    3724                 :             :           lhs = new_lhs;
    3725                 :             :         }
    3726                 :          53 :       edge succ_edge = single_succ_edge (bb);
    3727                 :          53 :       basic_block succ_bb = succ_edge->dest;
    3728                 :          53 :       gsi = gsi_start_phis (succ_bb);
    3729                 :          53 :       if (gsi_end_p (gsi))
    3730                 :             :         return;
    3731                 :          53 :       gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
    3732                 :          53 :       gsi_next (&gsi);
    3733                 :          53 :       if (!gsi_end_p (gsi))
    3734                 :             :         return;
    3735                 :          53 :       if (gimple_phi_arg_def (phi, succ_edge->dest_idx) != lhs)
    3736                 :             :         return;
    3737                 :          53 :       tree other_val = gimple_phi_arg_def (phi, other_edge->dest_idx);
    3738                 :          53 :       if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
    3739                 :             :         {
    3740                 :           0 :           tree cond = gimple_assign_rhs1 (cond_stmt);
    3741                 :           0 :           if (TREE_CODE (cond) == NE_EXPR)
    3742                 :             :             {
    3743                 :           0 :               if (!operand_equal_p (other_val,
    3744                 :           0 :                                     gimple_assign_rhs3 (cond_stmt), 0))
    3745                 :             :                 return;
    3746                 :             :             }
    3747                 :           0 :           else if (!operand_equal_p (other_val,
    3748                 :           0 :                                      gimple_assign_rhs2 (cond_stmt), 0))
    3749                 :             :             return;
    3750                 :             :         }
    3751                 :          53 :       else if (gimple_assign_rhs_code (cond_stmt) == NE_EXPR)
    3752                 :             :         {
    3753                 :          24 :           if (!integer_zerop (other_val))
    3754                 :             :             return;
    3755                 :             :         }
    3756                 :          29 :       else if (!integer_onep (other_val))
    3757                 :             :         return;
    3758                 :             :     }
    3759                 :          93 :   if (pred_edge->flags & EDGE_TRUE_VALUE)
    3760                 :          40 :     gimple_cond_make_true (zero_cond);
    3761                 :             :   else
    3762                 :          53 :     gimple_cond_make_false (zero_cond);
    3763                 :          93 :   update_stmt (zero_cond);
    3764                 :          93 :   *cfg_changed = true;
    3765                 :             : }
    3766                 :             : 
    3767                 :             : /* Helper function for arith_overflow_check_p.  Return true
    3768                 :             :    if VAL1 is equal to VAL2 cast to corresponding integral type
    3769                 :             :    with other signedness or vice versa.  */
    3770                 :             : 
    3771                 :             : static bool
    3772                 :         382 : arith_cast_equal_p (tree val1, tree val2)
    3773                 :             : {
    3774                 :         382 :   if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
    3775                 :          65 :     return wi::eq_p (wi::to_wide (val1), wi::to_wide (val2));
    3776                 :         317 :   else if (TREE_CODE (val1) != SSA_NAME || TREE_CODE (val2) != SSA_NAME)
    3777                 :             :     return false;
    3778                 :         280 :   if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val1))
    3779                 :         280 :       && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val1)) == val2)
    3780                 :             :     return true;
    3781                 :         168 :   if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val2))
    3782                 :         168 :       && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val2)) == val1)
    3783                 :         120 :     return true;
    3784                 :             :   return false;
    3785                 :             : }
    3786                 :             : 
    3787                 :             : /* Helper function of match_arith_overflow.  Return 1
    3788                 :             :    if USE_STMT is unsigned overflow check ovf != 0 for
    3789                 :             :    STMT, -1 if USE_STMT is unsigned overflow check ovf == 0
    3790                 :             :    and 0 otherwise.  */
    3791                 :             : 
    3792                 :             : static int
    3793                 :     2570042 : arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
    3794                 :             :                         tree maxval, tree *other)
    3795                 :             : {
    3796                 :     2570042 :   enum tree_code ccode = ERROR_MARK;
    3797                 :     2570042 :   tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
    3798                 :     2570042 :   enum tree_code code = gimple_assign_rhs_code (stmt);
    3799                 :     5125243 :   tree lhs = gimple_assign_lhs (cast_stmt ? cast_stmt : stmt);
    3800                 :     2570042 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    3801                 :     2570042 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    3802                 :     2570042 :   tree multop = NULL_TREE, divlhs = NULL_TREE;
    3803                 :     2570042 :   gimple *cur_use_stmt = use_stmt;
    3804                 :             : 
    3805                 :     2570042 :   if (code == MULT_EXPR)
    3806                 :             :     {
    3807                 :      539189 :       if (!is_gimple_assign (use_stmt))
    3808                 :      538895 :         return 0;
    3809                 :      448511 :       if (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR)
    3810                 :             :         return 0;
    3811                 :        2366 :       if (gimple_assign_rhs1 (use_stmt) != lhs)
    3812                 :             :         return 0;
    3813                 :        2303 :       if (cast_stmt)
    3814                 :             :         {
    3815                 :         155 :           if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs1))
    3816                 :             :             multop = rhs2;
    3817                 :          81 :           else if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs2))
    3818                 :             :             multop = rhs1;
    3819                 :             :           else
    3820                 :             :             return 0;
    3821                 :             :         }
    3822                 :        2148 :       else if (gimple_assign_rhs2 (use_stmt) == rhs1)
    3823                 :             :         multop = rhs2;
    3824                 :        2072 :       else if (operand_equal_p (gimple_assign_rhs2 (use_stmt), rhs2, 0))
    3825                 :             :         multop = rhs1;
    3826                 :             :       else
    3827                 :             :         return 0;
    3828                 :         298 :       if (stmt_ends_bb_p (use_stmt))
    3829                 :             :         return 0;
    3830                 :         298 :       divlhs = gimple_assign_lhs (use_stmt);
    3831                 :         298 :       if (!divlhs)
    3832                 :             :         return 0;
    3833                 :         298 :       use_operand_p use;
    3834                 :         298 :       if (!single_imm_use (divlhs, &use, &cur_use_stmt))
    3835                 :             :         return 0;
    3836                 :         294 :       if (cast_stmt && gimple_assign_cast_p (cur_use_stmt))
    3837                 :             :         {
    3838                 :           4 :           tree cast_lhs = gimple_assign_lhs (cur_use_stmt);
    3839                 :           8 :           if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
    3840                 :           4 :               && TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
    3841                 :           4 :               && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
    3842                 :           4 :                   == TYPE_PRECISION (TREE_TYPE (divlhs)))
    3843                 :           8 :               && single_imm_use (cast_lhs, &use, &cur_use_stmt))
    3844                 :             :             {
    3845                 :             :               cast_stmt = NULL;
    3846                 :             :               divlhs = cast_lhs;
    3847                 :             :             }
    3848                 :             :           else
    3849                 :           0 :             return 0;
    3850                 :             :         }
    3851                 :             :     }
    3852                 :     2031147 :   if (gimple_code (cur_use_stmt) == GIMPLE_COND)
    3853                 :             :     {
    3854                 :      514513 :       ccode = gimple_cond_code (cur_use_stmt);
    3855                 :      514513 :       crhs1 = gimple_cond_lhs (cur_use_stmt);
    3856                 :      514513 :       crhs2 = gimple_cond_rhs (cur_use_stmt);
    3857                 :             :     }
    3858                 :     1516634 :   else if (is_gimple_assign (cur_use_stmt))
    3859                 :             :     {
    3860                 :      745775 :       if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
    3861                 :             :         {
    3862                 :      462905 :           ccode = gimple_assign_rhs_code (cur_use_stmt);
    3863                 :      462905 :           crhs1 = gimple_assign_rhs1 (cur_use_stmt);
    3864                 :      462905 :           crhs2 = gimple_assign_rhs2 (cur_use_stmt);
    3865                 :             :         }
    3866                 :      282870 :       else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
    3867                 :             :         {
    3868                 :        4844 :           tree cond = gimple_assign_rhs1 (cur_use_stmt);
    3869                 :        4844 :           if (COMPARISON_CLASS_P (cond))
    3870                 :             :             {
    3871                 :           0 :               ccode = TREE_CODE (cond);
    3872                 :           0 :               crhs1 = TREE_OPERAND (cond, 0);
    3873                 :           0 :               crhs2 = TREE_OPERAND (cond, 1);
    3874                 :             :             }
    3875                 :             :           else
    3876                 :             :             return 0;
    3877                 :             :         }
    3878                 :             :       else
    3879                 :             :         return 0;
    3880                 :             :     }
    3881                 :             :   else
    3882                 :             :     return 0;
    3883                 :             : 
    3884                 :      977418 :   if (maxval
    3885                 :      977418 :       && ccode == RSHIFT_EXPR
    3886                 :         105 :       && crhs1 == lhs
    3887                 :          25 :       && TREE_CODE (crhs2) == INTEGER_CST
    3888                 :      977443 :       && wi::to_widest (crhs2) == TYPE_PRECISION (TREE_TYPE (maxval)))
    3889                 :             :     {
    3890                 :          16 :       tree shiftlhs = gimple_assign_lhs (use_stmt);
    3891                 :          16 :       if (!shiftlhs)
    3892                 :             :         return 0;
    3893                 :          16 :       use_operand_p use;
    3894                 :          16 :       if (!single_imm_use (shiftlhs, &use, &cur_use_stmt))
    3895                 :             :         return 0;
    3896                 :          12 :       if (gimple_code (cur_use_stmt) == GIMPLE_COND)
    3897                 :             :         {
    3898                 :           0 :           ccode = gimple_cond_code (cur_use_stmt);
    3899                 :           0 :           crhs1 = gimple_cond_lhs (cur_use_stmt);
    3900                 :           0 :           crhs2 = gimple_cond_rhs (cur_use_stmt);
    3901                 :             :         }
    3902                 :          12 :       else if (is_gimple_assign (cur_use_stmt))
    3903                 :             :         {
    3904                 :          12 :           if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
    3905                 :             :             {
    3906                 :           0 :               ccode = gimple_assign_rhs_code (cur_use_stmt);
    3907                 :           0 :               crhs1 = gimple_assign_rhs1 (cur_use_stmt);
    3908                 :           0 :               crhs2 = gimple_assign_rhs2 (cur_use_stmt);
    3909                 :             :             }
    3910                 :          12 :           else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
    3911                 :             :             {
    3912                 :           0 :               tree cond = gimple_assign_rhs1 (cur_use_stmt);
    3913                 :           0 :               if (COMPARISON_CLASS_P (cond))
    3914                 :             :                 {
    3915                 :           0 :                   ccode = TREE_CODE (cond);
    3916                 :           0 :                   crhs1 = TREE_OPERAND (cond, 0);
    3917                 :           0 :                   crhs2 = TREE_OPERAND (cond, 1);
    3918                 :             :                 }
    3919                 :             :               else
    3920                 :             :                 return 0;
    3921                 :             :             }
    3922                 :             :           else
    3923                 :             :             {
    3924                 :          12 :               enum tree_code sc = gimple_assign_rhs_code (cur_use_stmt);
    3925                 :          12 :               tree castlhs = gimple_assign_lhs (cur_use_stmt);
    3926                 :          12 :               if (!CONVERT_EXPR_CODE_P (sc)
    3927                 :          12 :                   || !castlhs
    3928                 :          12 :                   || !INTEGRAL_TYPE_P (TREE_TYPE (castlhs))
    3929                 :          24 :                   || (TYPE_PRECISION (TREE_TYPE (castlhs))
    3930                 :          12 :                       > TYPE_PRECISION (TREE_TYPE (maxval))))
    3931                 :             :                 return 0;
    3932                 :             :               return 1;
    3933                 :             :             }
    3934                 :             :         }
    3935                 :             :       else
    3936                 :             :         return 0;
    3937                 :           0 :       if ((ccode != EQ_EXPR && ccode != NE_EXPR)
    3938                 :           0 :           || crhs1 != shiftlhs
    3939                 :           0 :           || !integer_zerop (crhs2))
    3940                 :           0 :         return 0;
    3941                 :             :       return 1;
    3942                 :             :     }
    3943                 :             : 
    3944                 :      977402 :   if (TREE_CODE_CLASS (ccode) != tcc_comparison)
    3945                 :             :     return 0;
    3946                 :             : 
    3947                 :      549888 :   switch (ccode)
    3948                 :             :     {
    3949                 :       99839 :     case GT_EXPR:
    3950                 :       99839 :     case LE_EXPR:
    3951                 :       99839 :       if (maxval)
    3952                 :             :         {
    3953                 :             :           /* r = a + b; r > maxval or r <= maxval  */
    3954                 :          41 :           if (crhs1 == lhs
    3955                 :          36 :               && TREE_CODE (crhs2) == INTEGER_CST
    3956                 :          63 :               && tree_int_cst_equal (crhs2, maxval))
    3957                 :          12 :             return ccode == GT_EXPR ? 1 : -1;
    3958                 :             :           break;
    3959                 :             :         }
    3960                 :             :       /* r = a - b; r > a or r <= a
    3961                 :             :          r = a + b; a > r or a <= r or b > r or b <= r.  */
    3962                 :       99798 :       if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
    3963                 :       99736 :           || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2)
    3964                 :        8770 :               && crhs2 == lhs))
    3965                 :        9308 :         return ccode == GT_EXPR ? 1 : -1;
    3966                 :             :       /* r = ~a; b > r or b <= r.  */
    3967                 :       90966 :       if (code == BIT_NOT_EXPR && crhs2 == lhs)
    3968                 :             :         {
    3969                 :         190 :           if (other)
    3970                 :          95 :             *other = crhs1;
    3971                 :         222 :           return ccode == GT_EXPR ? 1 : -1;
    3972                 :             :         }
    3973                 :             :       break;
    3974                 :       58590 :     case LT_EXPR:
    3975                 :       58590 :     case GE_EXPR:
    3976                 :       58590 :       if (maxval)
    3977                 :             :         break;
    3978                 :             :       /* r = a - b; a < r or a >= r
    3979                 :             :          r = a + b; r < a or r >= a or r < b or r >= b.  */
    3980                 :       58588 :       if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
    3981                 :       58448 :           || (code == PLUS_EXPR && crhs1 == lhs
    3982                 :       26169 :               && (crhs2 == rhs1 || crhs2 == rhs2)))
    3983                 :        3665 :         return ccode == LT_EXPR ? 1 : -1;
    3984                 :             :       /* r = ~a; r < b or r >= b.  */
    3985                 :       54975 :       if (code == BIT_NOT_EXPR && crhs1 == lhs)
    3986                 :             :         {
    3987                 :         167 :           if (other)
    3988                 :          92 :             *other = crhs2;
    3989                 :         219 :           return ccode == LT_EXPR ? 1 : -1;
    3990                 :             :         }
    3991                 :             :       break;
    3992                 :      391459 :     case EQ_EXPR:
    3993                 :      391459 :     case NE_EXPR:
    3994                 :             :       /* r = a * b; _1 = r / a; _1 == b
    3995                 :             :          r = a * b; _1 = r / b; _1 == a
    3996                 :             :          r = a * b; _1 = r / a; _1 != b
    3997                 :             :          r = a * b; _1 = r / b; _1 != a.  */
    3998                 :      391459 :       if (code == MULT_EXPR)
    3999                 :             :         {
    4000                 :         291 :           if (cast_stmt)
    4001                 :             :             {
    4002                 :         146 :               if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
    4003                 :         146 :                   || (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
    4004                 :             :                 {
    4005                 :         146 :                   use_stmt = cur_use_stmt;
    4006                 :         216 :                   return ccode == NE_EXPR ? 1 : -1;
    4007                 :             :                 }
    4008                 :             :             }
    4009                 :          94 :           else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
    4010                 :         145 :                    || (crhs2 == divlhs && crhs1 == multop))
    4011                 :             :             {
    4012                 :         145 :               use_stmt = cur_use_stmt;
    4013                 :         221 :               return ccode == NE_EXPR ? 1 : -1;
    4014                 :             :             }
    4015                 :             :         }
    4016                 :             :       break;
    4017                 :             :     default:
    4018                 :             :       break;
    4019                 :             :     }
    4020                 :             :   return 0;
    4021                 :             : }
    4022                 :             : 
    4023                 :             : extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
    4024                 :             : extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree));
    4025                 :             : extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree));
    4026                 :             : 
    4027                 :             : extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
    4028                 :             : extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
    4029                 :             : extern bool gimple_signed_integer_sat_trunc (tree, tree*, tree (*)(tree));
    4030                 :             : 
    4031                 :             : static void
    4032                 :         145 : build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi,
    4033                 :             :                                                 internal_fn fn, tree lhs,
    4034                 :             :                                                 tree op_0, tree op_1)
    4035                 :             : {
    4036                 :         145 :   if (direct_internal_fn_supported_p (fn, TREE_TYPE (lhs), OPTIMIZE_FOR_BOTH))
    4037                 :             :     {
    4038                 :         145 :       gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
    4039                 :         145 :       gimple_call_set_lhs (call, lhs);
    4040                 :         145 :       gsi_replace (gsi, call, /* update_eh_info */ true);
    4041                 :             :     }
    4042                 :         145 : }
    4043                 :             : 
    4044                 :             : static bool
    4045                 :          41 : build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi,
    4046                 :             :                                                internal_fn fn, tree lhs,
    4047                 :             :                                                tree op_0, tree op_1)
    4048                 :             : {
    4049                 :          41 :   if (!direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
    4050                 :             :     return false;
    4051                 :             : 
    4052                 :          33 :   gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
    4053                 :          33 :   gimple_call_set_lhs (call, lhs);
    4054                 :          33 :   gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4055                 :             : 
    4056                 :          33 :   return true;
    4057                 :             : }
    4058                 :             : 
    4059                 :             : /*
    4060                 :             :  * Try to match saturation unsigned add with assign.
    4061                 :             :  *   _7 = _4 + _6;
    4062                 :             :  *   _8 = _4 > _7;
    4063                 :             :  *   _9 = (long unsigned int) _8;
    4064                 :             :  *   _10 = -_9;
    4065                 :             :  *   _12 = _7 | _10;
    4066                 :             :  *   =>
    4067                 :             :  *   _12 = .SAT_ADD (_4, _6);  */
    4068                 :             : 
    4069                 :             : static void
    4070                 :     2297694 : match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt)
    4071                 :             : {
    4072                 :     2297694 :   tree ops[2];
    4073                 :     2297694 :   tree lhs = gimple_assign_lhs (stmt);
    4074                 :             : 
    4075                 :     2297694 :   if (gimple_unsigned_integer_sat_add (lhs, ops, NULL))
    4076                 :          34 :     build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
    4077                 :             :                                                     ops[0], ops[1]);
    4078                 :     2297694 : }
    4079                 :             : 
    4080                 :             : /*
    4081                 :             :  * Try to match saturation add with PHI.
    4082                 :             :  * For unsigned integer:
    4083                 :             :  *   <bb 2> :
    4084                 :             :  *   _1 = x_3(D) + y_4(D);
    4085                 :             :  *   if (_1 >= x_3(D))
    4086                 :             :  *     goto <bb 3>; [INV]
    4087                 :             :  *   else
    4088                 :             :  *     goto <bb 4>; [INV]
    4089                 :             :  *
    4090                 :             :  *   <bb 3> :
    4091                 :             :  *
    4092                 :             :  *   <bb 4> :
    4093                 :             :  *   # _2 = PHI <255(2), _1(3)>
    4094                 :             :  *   =>
    4095                 :             :  *   <bb 4> [local count: 1073741824]:
    4096                 :             :  *   _2 = .SAT_ADD (x_4(D), y_5(D));
    4097                 :             :  *
    4098                 :             :  * For signed integer:
    4099                 :             :  *   x.0_1 = (long unsigned int) x_7(D);
    4100                 :             :  *   y.1_2 = (long unsigned int) y_8(D);
    4101                 :             :  *   _3 = x.0_1 + y.1_2;
    4102                 :             :  *   sum_9 = (int64_t) _3;
    4103                 :             :  *   _4 = x_7(D) ^ y_8(D);
    4104                 :             :  *   _5 = x_7(D) ^ sum_9;
    4105                 :             :  *   _15 = ~_4;
    4106                 :             :  *   _16 = _5 & _15;
    4107                 :             :  *   if (_16 < 0)
    4108                 :             :  *     goto <bb 3>; [41.00%]
    4109                 :             :  *   else
    4110                 :             :  *     goto <bb 4>; [59.00%]
    4111                 :             :  *   _11 = x_7(D) < 0;
    4112                 :             :  *   _12 = (long int) _11;
    4113                 :             :  *   _13 = -_12;
    4114                 :             :  *   _14 = _13 ^ 9223372036854775807;
    4115                 :             :  *   # _6 = PHI <_14(3), sum_9(2)>
    4116                 :             :  *   =>
    4117                 :             :  *   _6 = .SAT_ADD (x_5(D), y_6(D)); [tail call]  */
    4118                 :             : 
    4119                 :             : static bool
    4120                 :     4087058 : match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
    4121                 :             : {
    4122                 :     4087058 :   if (gimple_phi_num_args (phi) != 2)
    4123                 :             :     return false;
    4124                 :             : 
    4125                 :     3372080 :   tree ops[2];
    4126                 :     3372080 :   tree phi_result = gimple_phi_result (phi);
    4127                 :             : 
    4128                 :     3372080 :   if (!gimple_unsigned_integer_sat_add (phi_result, ops, NULL)
    4129                 :     3372080 :       && !gimple_signed_integer_sat_add (phi_result, ops, NULL))
    4130                 :             :     return false;
    4131                 :             : 
    4132                 :          21 :   if (!TYPE_UNSIGNED (TREE_TYPE (ops[0])) && TREE_CODE (ops[1]) == INTEGER_CST)
    4133                 :           0 :     ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
    4134                 :             : 
    4135                 :          21 :   return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_ADD,
    4136                 :             :                                                         phi_result, ops[0],
    4137                 :          21 :                                                         ops[1]);
    4138                 :             : }
    4139                 :             : 
    4140                 :             : /*
    4141                 :             :  * Try to match saturation unsigned sub.
    4142                 :             :  *   _1 = _4 >= _5;
    4143                 :             :  *   _3 = _4 - _5;
    4144                 :             :  *   _6 = _1 ? _3 : 0;
    4145                 :             :  *   =>
    4146                 :             :  *   _6 = .SAT_SUB (_4, _5);  */
    4147                 :             : 
    4148                 :             : static void
    4149                 :     3121643 : match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
    4150                 :             : {
    4151                 :     3121643 :   tree ops[2];
    4152                 :     3121643 :   tree lhs = gimple_assign_lhs (stmt);
    4153                 :             : 
    4154                 :     3121643 :   if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
    4155                 :         111 :     build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_SUB, lhs,
    4156                 :             :                                                     ops[0], ops[1]);
    4157                 :     3121643 : }
    4158                 :             : 
    4159                 :             : /*
    4160                 :             :  * Try to match saturation unsigned sub.
    4161                 :             :  *  <bb 2> [local count: 1073741824]:
    4162                 :             :  *  if (x_2(D) > y_3(D))
    4163                 :             :  *    goto <bb 3>; [50.00%]
    4164                 :             :  *  else
    4165                 :             :  *    goto <bb 4>; [50.00%]
    4166                 :             :  *
    4167                 :             :  *  <bb 3> [local count: 536870912]:
    4168                 :             :  *  _4 = x_2(D) - y_3(D);
    4169                 :             :  *
    4170                 :             :  *  <bb 4> [local count: 1073741824]:
    4171                 :             :  *  # _1 = PHI <0(2), _4(3)>
    4172                 :             :  *  =>
    4173                 :             :  *  <bb 4> [local count: 1073741824]:
    4174                 :             :  *  _1 = .SAT_SUB (x_2(D), y_3(D));  */
    4175                 :             : static bool
    4176                 :     4087041 : match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
    4177                 :             : {
    4178                 :     4087041 :   if (gimple_phi_num_args (phi) != 2)
    4179                 :             :     return false;
    4180                 :             : 
    4181                 :     3372063 :   tree ops[2];
    4182                 :     3372063 :   tree phi_result = gimple_phi_result (phi);
    4183                 :             : 
    4184                 :     3372063 :   if (!gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
    4185                 :     3372063 :       && !gimple_signed_integer_sat_sub (phi_result, ops, NULL))
    4186                 :             :     return false;
    4187                 :             : 
    4188                 :          20 :   return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_SUB,
    4189                 :             :                                                         phi_result, ops[0],
    4190                 :          20 :                                                         ops[1]);
    4191                 :             : }
    4192                 :             : 
    4193                 :             : /*
    4194                 :             :  * Try to match saturation unsigned sub.
    4195                 :             :  * uint16_t x_4(D);
    4196                 :             :  * uint8_t _6;
    4197                 :             :  * overflow_5 = x_4(D) > 255;
    4198                 :             :  * _1 = (unsigned char) x_4(D);
    4199                 :             :  * _2 = (unsigned char) overflow_5;
    4200                 :             :  * _3 = -_2;
    4201                 :             :  * _6 = _1 | _3;
    4202                 :             :  * =>
    4203                 :             :  * _6 = .SAT_TRUNC (x_4(D));
    4204                 :             :  * */
    4205                 :             : static void
    4206                 :     2493255 : match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
    4207                 :             : {
    4208                 :     2493255 :   tree ops[1];
    4209                 :     2493255 :   tree lhs = gimple_assign_lhs (stmt);
    4210                 :     2493255 :   tree type = TREE_TYPE (lhs);
    4211                 :             : 
    4212                 :     2493255 :   if (gimple_unsigned_integer_sat_trunc (lhs, ops, NULL)
    4213                 :     2493336 :     && direct_internal_fn_supported_p (IFN_SAT_TRUNC,
    4214                 :          81 :                                        tree_pair (type, TREE_TYPE (ops[0])),
    4215                 :             :                                        OPTIMIZE_FOR_BOTH))
    4216                 :             :     {
    4217                 :          60 :       gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
    4218                 :          60 :       gimple_call_set_lhs (call, lhs);
    4219                 :          60 :       gsi_replace (gsi, call, /* update_eh_info */ true);
    4220                 :             :     }
    4221                 :     2493255 : }
    4222                 :             : 
    4223                 :             : /*
    4224                 :             :  * Try to match saturation truncate.
    4225                 :             :  * Aka:
    4226                 :             :  *   x.0_1 = (unsigned long) x_4(D);
    4227                 :             :  *   _2 = x.0_1 + 2147483648;
    4228                 :             :  *   if (_2 > 4294967295)
    4229                 :             :  *     goto <bb 4>; [50.00%]
    4230                 :             :  *   else
    4231                 :             :  *     goto <bb 3>; [50.00%]
    4232                 :             :  * ;;    succ:       4
    4233                 :             :  * ;;                3
    4234                 :             :  *
    4235                 :             :  * ;;   basic block 3, loop depth 0
    4236                 :             :  * ;;    pred:       2
    4237                 :             :  *   trunc_5 = (int32_t) x_4(D);
    4238                 :             :  *   goto <bb 5>; [100.00%]
    4239                 :             :  * ;;    succ:       5
    4240                 :             :  *
    4241                 :             :  * ;;   basic block 4, loop depth 0
    4242                 :             :  * ;;    pred:       2
    4243                 :             :  *   _7 = x_4(D) < 0;
    4244                 :             :  *   _8 = (int) _7;
    4245                 :             :  *   _9 = -_8;
    4246                 :             :  *   _10 = _9 ^ 2147483647;
    4247                 :             :  * ;;    succ:       5
    4248                 :             :  *
    4249                 :             :  * ;;   basic block 5, loop depth 0
    4250                 :             :  * ;;    pred:       3
    4251                 :             :  * ;;                4
    4252                 :             :  *   # _3 = PHI <trunc_5(3), _10(4)>
    4253                 :             :  * =>
    4254                 :             :  * _6 = .SAT_TRUNC (x_4(D));
    4255                 :             :  */
    4256                 :             : 
    4257                 :             : static bool
    4258                 :     4087025 : match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
    4259                 :             : {
    4260                 :     4087025 :   if (gimple_phi_num_args (phi) != 2)
    4261                 :             :     return false;
    4262                 :             : 
    4263                 :     3372047 :   tree ops[1];
    4264                 :     3372047 :   tree phi_result = gimple_phi_result (phi);
    4265                 :     3372047 :   tree type = TREE_TYPE (phi_result);
    4266                 :             : 
    4267                 :     3372047 :   if (!gimple_unsigned_integer_sat_trunc (phi_result, ops, NULL)
    4268                 :     3372047 :       && !gimple_signed_integer_sat_trunc (phi_result, ops, NULL))
    4269                 :             :     return false;
    4270                 :             : 
    4271                 :           0 :   if (!direct_internal_fn_supported_p (IFN_SAT_TRUNC,
    4272                 :           0 :                                        tree_pair (type, TREE_TYPE (ops[0])),
    4273                 :             :                                        OPTIMIZE_FOR_BOTH))
    4274                 :             :     return false;
    4275                 :             : 
    4276                 :           0 :   gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
    4277                 :           0 :   gimple_call_set_lhs (call, phi_result);
    4278                 :           0 :   gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4279                 :             : 
    4280                 :           0 :   return true;
    4281                 :             : }
    4282                 :             : 
    4283                 :             : /* Recognize for unsigned x
    4284                 :             :    x = y - z;
    4285                 :             :    if (x > y)
    4286                 :             :    where there are other uses of x and replace it with
    4287                 :             :    _7 = .SUB_OVERFLOW (y, z);
    4288                 :             :    x = REALPART_EXPR <_7>;
    4289                 :             :    _8 = IMAGPART_EXPR <_7>;
    4290                 :             :    if (_8)
    4291                 :             :    and similarly for addition.
    4292                 :             : 
    4293                 :             :    Also recognize:
    4294                 :             :    yc = (type) y;
    4295                 :             :    zc = (type) z;
    4296                 :             :    x = yc + zc;
    4297                 :             :    if (x > max)
    4298                 :             :    where y and z have unsigned types with maximum max
    4299                 :             :    and there are other uses of x and all of those cast x
    4300                 :             :    back to that unsigned type and again replace it with
    4301                 :             :    _7 = .ADD_OVERFLOW (y, z);
    4302                 :             :    _9 = REALPART_EXPR <_7>;
    4303                 :             :    _8 = IMAGPART_EXPR <_7>;
    4304                 :             :    if (_8)
    4305                 :             :    and replace (utype) x with _9.
    4306                 :             :    Or with x >> popcount (max) instead of x > max.
    4307                 :             : 
    4308                 :             :    Also recognize:
    4309                 :             :    x = ~z;
    4310                 :             :    if (y > x)
    4311                 :             :    and replace it with
    4312                 :             :    _7 = .ADD_OVERFLOW (y, z);
    4313                 :             :    _8 = IMAGPART_EXPR <_7>;
    4314                 :             :    if (_8)
    4315                 :             : 
    4316                 :             :    And also recognize:
    4317                 :             :    z = x * y;
    4318                 :             :    if (x != 0)
    4319                 :             :      goto <bb 3>; [50.00%]
    4320                 :             :    else
    4321                 :             :      goto <bb 4>; [50.00%]
    4322                 :             : 
    4323                 :             :    <bb 3> [local count: 536870913]:
    4324                 :             :    _2 = z / x;
    4325                 :             :    _9 = _2 != y;
    4326                 :             :    _10 = (int) _9;
    4327                 :             : 
    4328                 :             :    <bb 4> [local count: 1073741824]:
    4329                 :             :    # iftmp.0_3 = PHI <_10(3), 0(2)>
    4330                 :             :    and replace it with
    4331                 :             :    _7 = .MUL_OVERFLOW (x, y);
    4332                 :             :    z = IMAGPART_EXPR <_7>;
    4333                 :             :    _8 = IMAGPART_EXPR <_7>;
    4334                 :             :    _9 = _8 != 0;
    4335                 :             :    iftmp.0_3 = (int) _9;  */
    4336                 :             : 
    4337                 :             : static bool
    4338                 :     3058261 : match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
    4339                 :             :                       enum tree_code code, bool *cfg_changed)
    4340                 :             : {
    4341                 :     3058261 :   tree lhs = gimple_assign_lhs (stmt);
    4342                 :     3058261 :   tree type = TREE_TYPE (lhs);
    4343                 :     3058261 :   use_operand_p use_p;
    4344                 :     3058261 :   imm_use_iterator iter;
    4345                 :     3058261 :   bool use_seen = false;
    4346                 :     3058261 :   bool ovf_use_seen = false;
    4347                 :     3058261 :   gimple *use_stmt;
    4348                 :     3058261 :   gimple *add_stmt = NULL;
    4349                 :     3058261 :   bool add_first = false;
    4350                 :     3058261 :   gimple *cond_stmt = NULL;
    4351                 :     3058261 :   gimple *cast_stmt = NULL;
    4352                 :     3058261 :   tree cast_lhs = NULL_TREE;
    4353                 :             : 
    4354                 :     3058261 :   gcc_checking_assert (code == PLUS_EXPR
    4355                 :             :                        || code == MINUS_EXPR
    4356                 :             :                        || code == MULT_EXPR
    4357                 :             :                        || code == BIT_NOT_EXPR);
    4358                 :     3058261 :   if (!INTEGRAL_TYPE_P (type)
    4359                 :     2546595 :       || !TYPE_UNSIGNED (type)
    4360                 :     1742632 :       || has_zero_uses (lhs)
    4361                 :     3058261 :       || (code != PLUS_EXPR
    4362                 :     1742356 :           && code != MULT_EXPR
    4363                 :      151452 :           && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab,
    4364                 :      129807 :                             TYPE_MODE (type)) == CODE_FOR_nothing))
    4365                 :     1317641 :     return false;
    4366                 :             : 
    4367                 :     1740620 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    4368                 :     1740620 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    4369                 :     4666140 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    4370                 :             :     {
    4371                 :     2931637 :       use_stmt = USE_STMT (use_p);
    4372                 :     2931637 :       if (is_gimple_debug (use_stmt))
    4373                 :      393551 :         continue;
    4374                 :             : 
    4375                 :     2538086 :       tree other = NULL_TREE;
    4376                 :     2538086 :       if (arith_overflow_check_p (stmt, NULL, use_stmt, NULL_TREE, &other))
    4377                 :             :         {
    4378                 :        6609 :           if (code == BIT_NOT_EXPR)
    4379                 :             :             {
    4380                 :         187 :               gcc_assert (other);
    4381                 :         187 :               if (TREE_CODE (other) != SSA_NAME)
    4382                 :           0 :                 return false;
    4383                 :         187 :               if (rhs2 == NULL)
    4384                 :         187 :                 rhs2 = other;
    4385                 :             :               else
    4386                 :             :                 return false;
    4387                 :         187 :               cond_stmt = use_stmt;
    4388                 :             :             }
    4389                 :             :           ovf_use_seen = true;
    4390                 :             :         }
    4391                 :             :       else
    4392                 :             :         {
    4393                 :     2531477 :           use_seen = true;
    4394                 :     2531477 :           if (code == MULT_EXPR
    4395                 :     2531477 :               && cast_stmt == NULL
    4396                 :     2531477 :               && gimple_assign_cast_p (use_stmt))
    4397                 :             :             {
    4398                 :       15694 :               cast_lhs = gimple_assign_lhs (use_stmt);
    4399                 :       31388 :               if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
    4400                 :       15190 :                   && !TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
    4401                 :       28505 :                   && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
    4402                 :       12811 :                       == TYPE_PRECISION (TREE_TYPE (lhs))))
    4403                 :             :                 cast_stmt = use_stmt;
    4404                 :             :               else
    4405                 :             :                 cast_lhs = NULL_TREE;
    4406                 :             :             }
    4407                 :             :         }
    4408                 :     2538086 :       if (ovf_use_seen && use_seen)
    4409                 :             :         break;
    4410                 :             :     }
    4411                 :             : 
    4412                 :     1740620 :   if (!ovf_use_seen
    4413                 :     1740620 :       && code == MULT_EXPR
    4414                 :      394398 :       && cast_stmt)
    4415                 :             :     {
    4416                 :       12113 :       if (TREE_CODE (rhs1) != SSA_NAME
    4417                 :       12113 :           || (TREE_CODE (rhs2) != SSA_NAME && TREE_CODE (rhs2) != INTEGER_CST))
    4418                 :             :         return false;
    4419                 :       27694 :       FOR_EACH_IMM_USE_FAST (use_p, iter, cast_lhs)
    4420                 :             :         {
    4421                 :       15581 :           use_stmt = USE_STMT (use_p);
    4422                 :       15581 :           if (is_gimple_debug (use_stmt))
    4423                 :         837 :             continue;
    4424                 :             : 
    4425                 :       14744 :           if (arith_overflow_check_p (stmt, cast_stmt, use_stmt,
    4426                 :             :                                       NULL_TREE, NULL))
    4427                 :       15581 :             ovf_use_seen = true;
    4428                 :             :         }
    4429                 :             :     }
    4430                 :             :   else
    4431                 :             :     {
    4432                 :             :       cast_stmt = NULL;
    4433                 :             :       cast_lhs = NULL_TREE;
    4434                 :             :     }
    4435                 :             : 
    4436                 :     1740620 :   tree maxval = NULL_TREE;
    4437                 :     1740620 :   if (!ovf_use_seen
    4438                 :       13221 :       || (code != MULT_EXPR && (code == BIT_NOT_EXPR ? use_seen : !use_seen))
    4439                 :        6235 :       || (code == PLUS_EXPR
    4440                 :        5965 :           && optab_handler (uaddv4_optab,
    4441                 :        5965 :                             TYPE_MODE (type)) == CODE_FOR_nothing)
    4442                 :     1753539 :       || (code == MULT_EXPR
    4443                 :         219 :           && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
    4444                 :         147 :                             TYPE_MODE (type)) == CODE_FOR_nothing
    4445                 :           3 :           && (use_seen
    4446                 :           3 :               || cast_stmt
    4447                 :           0 :               || !can_mult_highpart_p (TYPE_MODE (type), true))))
    4448                 :             :     {
    4449                 :     1734241 :       if (code != PLUS_EXPR)
    4450                 :             :         return false;
    4451                 :     1212114 :       if (TREE_CODE (rhs1) != SSA_NAME
    4452                 :     1212114 :           || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
    4453                 :             :         return false;
    4454                 :      290470 :       rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
    4455                 :      290470 :       tree type1 = TREE_TYPE (rhs1);
    4456                 :      290470 :       if (!INTEGRAL_TYPE_P (type1)
    4457                 :      157012 :           || !TYPE_UNSIGNED (type1)
    4458                 :       34832 :           || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
    4459                 :      305391 :           || (TYPE_PRECISION (type1)
    4460                 :       29842 :               != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
    4461                 :      280988 :         return false;
    4462                 :        9482 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    4463                 :             :         {
    4464                 :        3596 :           if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
    4465                 :        3596 :                                     TYPE_PRECISION (type1),
    4466                 :        7192 :                                     UNSIGNED), 0))
    4467                 :             :             return false;
    4468                 :        1116 :           rhs2 = fold_convert (type1, rhs2);
    4469                 :             :         }
    4470                 :             :       else
    4471                 :             :         {
    4472                 :        5886 :           if (TREE_CODE (rhs2) != SSA_NAME
    4473                 :        5886 :               || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
    4474                 :             :             return false;
    4475                 :        2650 :           rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
    4476                 :        2650 :           tree type2 = TREE_TYPE (rhs2);
    4477                 :        2650 :           if (!INTEGRAL_TYPE_P (type2)
    4478                 :        1074 :               || !TYPE_UNSIGNED (type2)
    4479                 :         368 :               || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
    4480                 :        2974 :               || (TYPE_PRECISION (type2)
    4481                 :         648 :                   != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
    4482                 :        2338 :             return false;
    4483                 :             :         }
    4484                 :        1428 :       if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
    4485                 :             :         type = type1;
    4486                 :             :       else
    4487                 :           5 :         type = TREE_TYPE (rhs2);
    4488                 :             : 
    4489                 :        1428 :       if (TREE_CODE (type) != INTEGER_TYPE
    4490                 :        2854 :           || optab_handler (uaddv4_optab,
    4491                 :        1426 :                             TYPE_MODE (type)) == CODE_FOR_nothing)
    4492                 :           2 :         return false;
    4493                 :             : 
    4494                 :        1426 :       maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
    4495                 :             :                                                       UNSIGNED));
    4496                 :        1426 :       ovf_use_seen = false;
    4497                 :        1426 :       use_seen = false;
    4498                 :        1426 :       basic_block use_bb = NULL;
    4499                 :        1462 :       FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    4500                 :             :         {
    4501                 :        1438 :           use_stmt = USE_STMT (use_p);
    4502                 :        1438 :           if (is_gimple_debug (use_stmt))
    4503                 :           8 :             continue;
    4504                 :             : 
    4505                 :        1430 :           if (arith_overflow_check_p (stmt, NULL, use_stmt, maxval, NULL))
    4506                 :             :             {
    4507                 :          12 :               ovf_use_seen = true;
    4508                 :          12 :               use_bb = gimple_bb (use_stmt);
    4509                 :             :             }
    4510                 :             :           else
    4511                 :             :             {
    4512                 :        1418 :               if (!gimple_assign_cast_p (use_stmt)
    4513                 :        1418 :                   || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
    4514                 :             :                 return false;
    4515                 :          68 :               tree use_lhs = gimple_assign_lhs (use_stmt);
    4516                 :         136 :               if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
    4517                 :         136 :                   || (TYPE_PRECISION (TREE_TYPE (use_lhs))
    4518                 :          68 :                       > TYPE_PRECISION (type)))
    4519                 :             :                 return false;
    4520                 :             :               use_seen = true;
    4521                 :             :             }
    4522                 :             :         }
    4523                 :          24 :       if (!ovf_use_seen)
    4524                 :             :         return false;
    4525                 :          12 :       if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
    4526                 :             :         {
    4527                 :           2 :           if (!use_seen)
    4528                 :             :             return false;
    4529                 :           2 :           tree new_rhs1 = make_ssa_name (type);
    4530                 :           2 :           gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
    4531                 :           2 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4532                 :           2 :           rhs1 = new_rhs1;
    4533                 :             :         }
    4534                 :          10 :       else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
    4535                 :             :         {
    4536                 :           2 :           if (!use_seen)
    4537                 :             :             return false;
    4538                 :           2 :           tree new_rhs2 = make_ssa_name (type);
    4539                 :           2 :           gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
    4540                 :           2 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4541                 :           2 :           rhs2 = new_rhs2;
    4542                 :             :         }
    4543                 :           8 :       else if (!use_seen)
    4544                 :             :         {
    4545                 :             :           /* If there are no uses of the wider addition, check if
    4546                 :             :              forwprop has not created a narrower addition.
    4547                 :             :              Require it to be in the same bb as the overflow check.  */
    4548                 :          10 :           FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
    4549                 :             :             {
    4550                 :          10 :               use_stmt = USE_STMT (use_p);
    4551                 :          10 :               if (is_gimple_debug (use_stmt))
    4552                 :           0 :                 continue;
    4553                 :             : 
    4554                 :          10 :               if (use_stmt == stmt)
    4555                 :           0 :                 continue;
    4556                 :             : 
    4557                 :          10 :               if (!is_gimple_assign (use_stmt)
    4558                 :          10 :                   || gimple_bb (use_stmt) != use_bb
    4559                 :          20 :                   || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
    4560                 :           2 :                 continue;
    4561                 :             : 
    4562                 :           8 :               if (gimple_assign_rhs1 (use_stmt) == rhs1)
    4563                 :             :                 {
    4564                 :           8 :                   if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
    4565                 :             :                                         rhs2, 0))
    4566                 :           0 :                     continue;
    4567                 :             :                 }
    4568                 :           0 :               else if (gimple_assign_rhs2 (use_stmt) == rhs1)
    4569                 :             :                 {
    4570                 :           0 :                   if (gimple_assign_rhs1 (use_stmt) != rhs2)
    4571                 :           0 :                     continue;
    4572                 :             :                 }
    4573                 :             :               else
    4574                 :           0 :                 continue;
    4575                 :             : 
    4576                 :           8 :               add_stmt = use_stmt;
    4577                 :           8 :               break;
    4578                 :             :             }
    4579                 :           8 :           if (add_stmt == NULL)
    4580                 :             :             return false;
    4581                 :             : 
    4582                 :             :           /* If stmt and add_stmt are in the same bb, we need to find out
    4583                 :             :              which one is earlier.  If they are in different bbs, we've
    4584                 :             :              checked add_stmt is in the same bb as one of the uses of the
    4585                 :             :              stmt lhs, so stmt needs to dominate add_stmt too.  */
    4586                 :           8 :           if (gimple_bb (stmt) == gimple_bb (add_stmt))
    4587                 :             :             {
    4588                 :           8 :               gimple_stmt_iterator gsif = *gsi;
    4589                 :           8 :               gimple_stmt_iterator gsib = *gsi;
    4590                 :           8 :               int i;
    4591                 :             :               /* Search both forward and backward from stmt and have a small
    4592                 :             :                  upper bound.  */
    4593                 :          20 :               for (i = 0; i < 128; i++)
    4594                 :             :                 {
    4595                 :          20 :                   if (!gsi_end_p (gsib))
    4596                 :             :                     {
    4597                 :          18 :                       gsi_prev_nondebug (&gsib);
    4598                 :          18 :                       if (gsi_stmt (gsib) == add_stmt)
    4599                 :             :                         {
    4600                 :             :                           add_first = true;
    4601                 :             :                           break;
    4602                 :             :                         }
    4603                 :             :                     }
    4604                 :           2 :                   else if (gsi_end_p (gsif))
    4605                 :             :                     break;
    4606                 :          18 :                   if (!gsi_end_p (gsif))
    4607                 :             :                     {
    4608                 :          18 :                       gsi_next_nondebug (&gsif);
    4609                 :          18 :                       if (gsi_stmt (gsif) == add_stmt)
    4610                 :             :                         break;
    4611                 :             :                     }
    4612                 :             :                 }
    4613                 :           8 :               if (i == 128)
    4614                 :           0 :                 return false;
    4615                 :           8 :               if (add_first)
    4616                 :           2 :                 *gsi = gsi_for_stmt (add_stmt);
    4617                 :             :             }
    4618                 :             :         }
    4619                 :             :     }
    4620                 :             : 
    4621                 :        6391 :   if (code == BIT_NOT_EXPR)
    4622                 :         170 :     *gsi = gsi_for_stmt (cond_stmt);
    4623                 :             : 
    4624                 :        6391 :   auto_vec<gimple *, 8> mul_stmts;
    4625                 :        6391 :   if (code == MULT_EXPR && cast_stmt)
    4626                 :             :     {
    4627                 :          75 :       type = TREE_TYPE (cast_lhs);
    4628                 :          75 :       gimple *g = SSA_NAME_DEF_STMT (rhs1);
    4629                 :          75 :       if (gimple_assign_cast_p (g)
    4630                 :          38 :           && useless_type_conversion_p (type,
    4631                 :          38 :                                         TREE_TYPE (gimple_assign_rhs1 (g)))
    4632                 :         113 :           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
    4633                 :             :         rhs1 = gimple_assign_rhs1 (g);
    4634                 :             :       else
    4635                 :             :         {
    4636                 :          37 :           g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs1);
    4637                 :          37 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4638                 :          37 :           rhs1 = gimple_assign_lhs (g);
    4639                 :          37 :           mul_stmts.quick_push (g);
    4640                 :             :         }
    4641                 :          75 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    4642                 :          32 :         rhs2 = fold_convert (type, rhs2);
    4643                 :             :       else
    4644                 :             :         {
    4645                 :          43 :           g = SSA_NAME_DEF_STMT (rhs2);
    4646                 :          43 :           if (gimple_assign_cast_p (g)
    4647                 :          22 :               && useless_type_conversion_p (type,
    4648                 :          22 :                                             TREE_TYPE (gimple_assign_rhs1 (g)))
    4649                 :          65 :               && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
    4650                 :             :             rhs2 = gimple_assign_rhs1 (g);
    4651                 :             :           else
    4652                 :             :             {
    4653                 :          21 :               g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs2);
    4654                 :          21 :               gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4655                 :          21 :               rhs2 = gimple_assign_lhs (g);
    4656                 :          21 :               mul_stmts.quick_push (g);
    4657                 :             :             }
    4658                 :             :         }
    4659                 :             :     }
    4660                 :        6391 :   tree ctype = build_complex_type (type);
    4661                 :       12638 :   gcall *g = gimple_build_call_internal (code == MULT_EXPR
    4662                 :             :                                          ? IFN_MUL_OVERFLOW
    4663                 :             :                                          : code != MINUS_EXPR
    4664                 :        6247 :                                          ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
    4665                 :             :                                          2, rhs1, rhs2);
    4666                 :        6391 :   tree ctmp = make_ssa_name (ctype);
    4667                 :        6391 :   gimple_call_set_lhs (g, ctmp);
    4668                 :        6391 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4669                 :        6391 :   tree new_lhs = (maxval || cast_stmt) ? make_ssa_name (type) : lhs;
    4670                 :        6391 :   gassign *g2;
    4671                 :        6391 :   if (code != BIT_NOT_EXPR)
    4672                 :             :     {
    4673                 :        6221 :       g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
    4674                 :             :                                 build1 (REALPART_EXPR, type, ctmp));
    4675                 :        6221 :       if (maxval || cast_stmt)
    4676                 :             :         {
    4677                 :          87 :           gsi_insert_before (gsi, g2, GSI_SAME_STMT);
    4678                 :          87 :           if (add_first)
    4679                 :           2 :             *gsi = gsi_for_stmt (stmt);
    4680                 :             :         }
    4681                 :             :       else
    4682                 :        6134 :         gsi_replace (gsi, g2, true);
    4683                 :        6221 :       if (code == MULT_EXPR)
    4684                 :             :         {
    4685                 :         144 :           mul_stmts.quick_push (g);
    4686                 :         144 :           mul_stmts.quick_push (g2);
    4687                 :         144 :           if (cast_stmt)
    4688                 :             :             {
    4689                 :          75 :               g2 = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
    4690                 :          75 :               gsi_replace (gsi, g2, true);
    4691                 :          75 :               mul_stmts.quick_push (g2);
    4692                 :             :             }
    4693                 :             :         }
    4694                 :             :     }
    4695                 :        6391 :   tree ovf = make_ssa_name (type);
    4696                 :        6391 :   g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
    4697                 :             :                             build1 (IMAGPART_EXPR, type, ctmp));
    4698                 :        6391 :   if (code != BIT_NOT_EXPR)
    4699                 :        6221 :     gsi_insert_after (gsi, g2, GSI_NEW_STMT);
    4700                 :             :   else
    4701                 :         170 :     gsi_insert_before (gsi, g2, GSI_SAME_STMT);
    4702                 :        6391 :   if (code == MULT_EXPR)
    4703                 :         144 :     mul_stmts.quick_push (g2);
    4704                 :             : 
    4705                 :       32792 :   FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
    4706                 :             :     {
    4707                 :       20085 :       if (is_gimple_debug (use_stmt))
    4708                 :        4303 :         continue;
    4709                 :             : 
    4710                 :       15782 :       gimple *orig_use_stmt = use_stmt;
    4711                 :       15782 :       int ovf_use = arith_overflow_check_p (stmt, cast_stmt, use_stmt,
    4712                 :             :                                             maxval, NULL);
    4713                 :       15782 :       if (ovf_use == 0)
    4714                 :             :         {
    4715                 :        9361 :           gcc_assert (code != BIT_NOT_EXPR);
    4716                 :        9361 :           if (maxval)
    4717                 :             :             {
    4718                 :           4 :               tree use_lhs = gimple_assign_lhs (use_stmt);
    4719                 :           4 :               gimple_assign_set_rhs1 (use_stmt, new_lhs);
    4720                 :           4 :               if (useless_type_conversion_p (TREE_TYPE (use_lhs),
    4721                 :           4 :                                              TREE_TYPE (new_lhs)))
    4722                 :           4 :                 gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
    4723                 :           4 :               update_stmt (use_stmt);
    4724                 :             :             }
    4725                 :        9361 :           continue;
    4726                 :        9361 :         }
    4727                 :        6421 :       if (gimple_code (use_stmt) == GIMPLE_COND)
    4728                 :             :         {
    4729                 :        4308 :           gcond *cond_stmt = as_a <gcond *> (use_stmt);
    4730                 :        4308 :           gimple_cond_set_lhs (cond_stmt, ovf);
    4731                 :        4308 :           gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
    4732                 :        4532 :           gimple_cond_set_code (cond_stmt, ovf_use == 1 ? NE_EXPR : EQ_EXPR);
    4733                 :             :         }
    4734                 :             :       else
    4735                 :             :         {
    4736                 :        2113 :           gcc_checking_assert (is_gimple_assign (use_stmt));
    4737                 :        2113 :           if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
    4738                 :             :             {
    4739                 :        2113 :               if (gimple_assign_rhs_code (use_stmt) == RSHIFT_EXPR)
    4740                 :             :                 {
    4741                 :           6 :                   g2 = gimple_build_assign (make_ssa_name (boolean_type_node),
    4742                 :             :                                             ovf_use == 1 ? NE_EXPR : EQ_EXPR,
    4743                 :           6 :                                             ovf, build_int_cst (type, 0));
    4744                 :           6 :                   gimple_stmt_iterator gsiu = gsi_for_stmt (use_stmt);
    4745                 :           6 :                   gsi_insert_before (&gsiu, g2, GSI_SAME_STMT);
    4746                 :           6 :                   gimple_assign_set_rhs_with_ops (&gsiu, NOP_EXPR,
    4747                 :             :                                                   gimple_assign_lhs (g2));
    4748                 :           6 :                   update_stmt (use_stmt);
    4749                 :           6 :                   use_operand_p use;
    4750                 :           6 :                   single_imm_use (gimple_assign_lhs (use_stmt), &use,
    4751                 :             :                                   &use_stmt);
    4752                 :           6 :                   if (gimple_code (use_stmt) == GIMPLE_COND)
    4753                 :             :                     {
    4754                 :           0 :                       gcond *cond_stmt = as_a <gcond *> (use_stmt);
    4755                 :           0 :                       gimple_cond_set_lhs (cond_stmt, ovf);
    4756                 :           0 :                       gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
    4757                 :             :                     }
    4758                 :             :                   else
    4759                 :             :                     {
    4760                 :           6 :                       gcc_checking_assert (is_gimple_assign (use_stmt));
    4761                 :           6 :                       if (gimple_assign_rhs_class (use_stmt)
    4762                 :             :                           == GIMPLE_BINARY_RHS)
    4763                 :             :                         {
    4764                 :           0 :                           gimple_assign_set_rhs1 (use_stmt, ovf);
    4765                 :           0 :                           gimple_assign_set_rhs2 (use_stmt,
    4766                 :           0 :                                                   build_int_cst (type, 0));
    4767                 :             :                         }
    4768                 :           6 :                       else if (gimple_assign_cast_p (use_stmt))
    4769                 :           6 :                         gimple_assign_set_rhs1 (use_stmt, ovf);
    4770                 :             :                       else
    4771                 :             :                         {
    4772                 :           0 :                           tree_code sc = gimple_assign_rhs_code (use_stmt);
    4773                 :           0 :                           gcc_checking_assert (sc == COND_EXPR);
    4774                 :           0 :                           tree cond = gimple_assign_rhs1 (use_stmt);
    4775                 :           0 :                           cond = build2 (TREE_CODE (cond),
    4776                 :             :                                          boolean_type_node, ovf,
    4777                 :           0 :                                          build_int_cst (type, 0));
    4778                 :           0 :                           gimple_assign_set_rhs1 (use_stmt, cond);
    4779                 :             :                         }
    4780                 :             :                     }
    4781                 :           6 :                   update_stmt (use_stmt);
    4782                 :           6 :                   gsi_remove (&gsiu, true);
    4783                 :           6 :                   gsiu = gsi_for_stmt (g2);
    4784                 :           6 :                   gsi_remove (&gsiu, true);
    4785                 :           6 :                   continue;
    4786                 :           6 :                 }
    4787                 :             :               else
    4788                 :             :                 {
    4789                 :        2107 :                   gimple_assign_set_rhs1 (use_stmt, ovf);
    4790                 :        2107 :                   gimple_assign_set_rhs2 (use_stmt, build_int_cst (type, 0));
    4791                 :        2256 :                   gimple_assign_set_rhs_code (use_stmt,
    4792                 :             :                                               ovf_use == 1
    4793                 :             :                                               ? NE_EXPR : EQ_EXPR);
    4794                 :             :                 }
    4795                 :             :             }
    4796                 :             :           else
    4797                 :             :             {
    4798                 :           0 :               gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
    4799                 :             :                                    == COND_EXPR);
    4800                 :           0 :               tree cond = build2 (ovf_use == 1 ? NE_EXPR : EQ_EXPR,
    4801                 :             :                                   boolean_type_node, ovf,
    4802                 :           0 :                                   build_int_cst (type, 0));
    4803                 :           0 :               gimple_assign_set_rhs1 (use_stmt, cond);
    4804                 :             :             }
    4805                 :             :         }
    4806                 :        6415 :       update_stmt (use_stmt);
    4807                 :        6415 :       if (code == MULT_EXPR && use_stmt != orig_use_stmt)
    4808                 :             :         {
    4809                 :         144 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (orig_use_stmt);
    4810                 :         144 :           maybe_optimize_guarding_check (mul_stmts, use_stmt, orig_use_stmt,
    4811                 :             :                                          cfg_changed);
    4812                 :         144 :           use_operand_p use;
    4813                 :         144 :           gimple *cast_stmt;
    4814                 :         144 :           if (single_imm_use (gimple_assign_lhs (orig_use_stmt), &use,
    4815                 :             :                               &cast_stmt)
    4816                 :         144 :               && gimple_assign_cast_p (cast_stmt))
    4817                 :             :             {
    4818                 :           2 :               gimple_stmt_iterator gsi3 = gsi_for_stmt (cast_stmt);
    4819                 :           2 :               gsi_remove (&gsi3, true);
    4820                 :           2 :               release_ssa_name (gimple_assign_lhs (cast_stmt));
    4821                 :             :             }
    4822                 :         144 :           gsi_remove (&gsi2, true);
    4823                 :         144 :           release_ssa_name (gimple_assign_lhs (orig_use_stmt));
    4824                 :             :         }
    4825                 :        6391 :     }
    4826                 :        6391 :   if (maxval)
    4827                 :             :     {
    4828                 :          12 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
    4829                 :          12 :       gsi_remove (&gsi2, true);
    4830                 :          12 :       if (add_stmt)
    4831                 :             :         {
    4832                 :           8 :           gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
    4833                 :             :                                            new_lhs);
    4834                 :           8 :           gsi2 = gsi_for_stmt (add_stmt);
    4835                 :           8 :           gsi_replace (&gsi2, g, true);
    4836                 :             :         }
    4837                 :             :     }
    4838                 :        6379 :   else if (code == BIT_NOT_EXPR)
    4839                 :             :     {
    4840                 :         170 :       *gsi = gsi_for_stmt (stmt);
    4841                 :         170 :       gsi_remove (gsi, true);
    4842                 :         170 :       release_ssa_name (lhs);
    4843                 :         170 :       return true;
    4844                 :             :     }
    4845                 :             :   return false;
    4846                 :        6391 : }
    4847                 :             : 
    4848                 :             : /* Helper of match_uaddc_usubc.  Look through an integral cast
    4849                 :             :    which should preserve [0, 1] range value (unless source has
    4850                 :             :    1-bit signed type) and the cast has single use.  */
    4851                 :             : 
    4852                 :             : static gimple *
    4853                 :     1879266 : uaddc_cast (gimple *g)
    4854                 :             : {
    4855                 :     1879266 :   if (!gimple_assign_cast_p (g))
    4856                 :             :     return g;
    4857                 :      440916 :   tree op = gimple_assign_rhs1 (g);
    4858                 :      440916 :   if (TREE_CODE (op) == SSA_NAME
    4859                 :      371717 :       && INTEGRAL_TYPE_P (TREE_TYPE (op))
    4860                 :      262965 :       && (TYPE_PRECISION (TREE_TYPE (op)) > 1
    4861                 :        6189 :           || TYPE_UNSIGNED (TREE_TYPE (op)))
    4862                 :      703881 :       && has_single_use (gimple_assign_lhs (g)))
    4863                 :      167878 :     return SSA_NAME_DEF_STMT (op);
    4864                 :             :   return g;
    4865                 :             : }
    4866                 :             : 
    4867                 :             : /* Helper of match_uaddc_usubc.  Look through a NE_EXPR
    4868                 :             :    comparison with 0 which also preserves [0, 1] value range.  */
    4869                 :             : 
    4870                 :             : static gimple *
    4871                 :     1879385 : uaddc_ne0 (gimple *g)
    4872                 :             : {
    4873                 :     1879385 :   if (is_gimple_assign (g)
    4874                 :     1146517 :       && gimple_assign_rhs_code (g) == NE_EXPR
    4875                 :       54065 :       && integer_zerop (gimple_assign_rhs2 (g))
    4876                 :        5613 :       && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
    4877                 :     1884998 :       && has_single_use (gimple_assign_lhs (g)))
    4878                 :        5413 :     return SSA_NAME_DEF_STMT (gimple_assign_rhs1 (g));
    4879                 :             :   return g;
    4880                 :             : }
    4881                 :             : 
    4882                 :             : /* Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
    4883                 :             :    operand.  */
    4884                 :             : 
    4885                 :             : static bool
    4886                 :     1880006 : uaddc_is_cplxpart (gimple *g, tree_code part)
    4887                 :             : {
    4888                 :     1880006 :   return (is_gimple_assign (g)
    4889                 :     1145250 :           && gimple_assign_rhs_code (g) == part
    4890                 :     1881999 :           && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (g), 0)) == SSA_NAME);
    4891                 :             : }
    4892                 :             : 
    4893                 :             : /* Try to match e.g.
    4894                 :             :    _29 = .ADD_OVERFLOW (_3, _4);
    4895                 :             :    _30 = REALPART_EXPR <_29>;
    4896                 :             :    _31 = IMAGPART_EXPR <_29>;
    4897                 :             :    _32 = .ADD_OVERFLOW (_30, _38);
    4898                 :             :    _33 = REALPART_EXPR <_32>;
    4899                 :             :    _34 = IMAGPART_EXPR <_32>;
    4900                 :             :    _35 = _31 + _34;
    4901                 :             :    as
    4902                 :             :    _36 = .UADDC (_3, _4, _38);
    4903                 :             :    _33 = REALPART_EXPR <_36>;
    4904                 :             :    _35 = IMAGPART_EXPR <_36>;
    4905                 :             :    or
    4906                 :             :    _22 = .SUB_OVERFLOW (_6, _5);
    4907                 :             :    _23 = REALPART_EXPR <_22>;
    4908                 :             :    _24 = IMAGPART_EXPR <_22>;
    4909                 :             :    _25 = .SUB_OVERFLOW (_23, _37);
    4910                 :             :    _26 = REALPART_EXPR <_25>;
    4911                 :             :    _27 = IMAGPART_EXPR <_25>;
    4912                 :             :    _28 = _24 | _27;
    4913                 :             :    as
    4914                 :             :    _29 = .USUBC (_6, _5, _37);
    4915                 :             :    _26 = REALPART_EXPR <_29>;
    4916                 :             :    _288 = IMAGPART_EXPR <_29>;
    4917                 :             :    provided _38 or _37 above have [0, 1] range
    4918                 :             :    and _3, _4 and _30 or _6, _5 and _23 are unsigned
    4919                 :             :    integral types with the same precision.  Whether + or | or ^ is
    4920                 :             :    used on the IMAGPART_EXPR results doesn't matter, with one of
    4921                 :             :    added or subtracted operands in [0, 1] range at most one
    4922                 :             :    .ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow.  */
    4923                 :             : 
    4924                 :             : static bool
    4925                 :     2587879 : match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
    4926                 :             : {
    4927                 :     2587879 :   tree rhs[4];
    4928                 :     2587879 :   rhs[0] = gimple_assign_rhs1 (stmt);
    4929                 :     2587879 :   rhs[1] = gimple_assign_rhs2 (stmt);
    4930                 :     2587879 :   rhs[2] = NULL_TREE;
    4931                 :     2587879 :   rhs[3] = NULL_TREE;
    4932                 :     2587879 :   tree type = TREE_TYPE (rhs[0]);
    4933                 :     2587879 :   if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))
    4934                 :             :     return false;
    4935                 :             : 
    4936                 :     1484899 :   auto_vec<gimple *, 2> temp_stmts;
    4937                 :     1484899 :   if (code != BIT_IOR_EXPR && code != BIT_XOR_EXPR)
    4938                 :             :     {
    4939                 :             :       /* If overflow flag is ignored on the MSB limb, we can end up with
    4940                 :             :          the most significant limb handled as r = op1 + op2 + ovf1 + ovf2;
    4941                 :             :          or r = op1 - op2 - ovf1 - ovf2; or various equivalent expressions
    4942                 :             :          thereof.  Handle those like the ovf = ovf1 + ovf2; case to recognize
    4943                 :             :          the limb below the MSB, but also create another .UADDC/.USUBC call
    4944                 :             :          for the last limb.
    4945                 :             : 
    4946                 :             :          First look through assignments with the same rhs code as CODE,
    4947                 :             :          with the exception that subtraction of a constant is canonicalized
    4948                 :             :          into addition of its negation.  rhs[0] will be minuend for
    4949                 :             :          subtractions and one of addends for addition, all other assigned
    4950                 :             :          rhs[i] operands will be subtrahends or other addends.  */
    4951                 :     1358127 :       while (TREE_CODE (rhs[0]) == SSA_NAME && !rhs[3])
    4952                 :             :         {
    4953                 :     1339180 :           gimple *g = SSA_NAME_DEF_STMT (rhs[0]);
    4954                 :     1339180 :           if (has_single_use (rhs[0])
    4955                 :      456441 :               && is_gimple_assign (g)
    4956                 :     1740351 :               && (gimple_assign_rhs_code (g) == code
    4957                 :      374972 :                   || (code == MINUS_EXPR
    4958                 :       47013 :                       && gimple_assign_rhs_code (g) == PLUS_EXPR
    4959                 :       14966 :                       && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST)))
    4960                 :             :             {
    4961                 :       37830 :               tree r2 = gimple_assign_rhs2 (g);
    4962                 :       37830 :               if (gimple_assign_rhs_code (g) != code)
    4963                 :             :                 {
    4964                 :       11631 :                   r2 = const_unop (NEGATE_EXPR, TREE_TYPE (r2), r2);
    4965                 :       11631 :                   if (!r2)
    4966                 :             :                     break;
    4967                 :             :                 }
    4968                 :       37830 :               rhs[0] = gimple_assign_rhs1 (g);
    4969                 :       37830 :               tree &r = rhs[2] ? rhs[3] : rhs[2];
    4970                 :       37830 :               r = r2;
    4971                 :       37830 :               temp_stmts.quick_push (g);
    4972                 :             :             }
    4973                 :             :           else
    4974                 :             :             break;
    4975                 :             :         }
    4976                 :     3960891 :       for (int i = 1; i <= 2; ++i)
    4977                 :     2685981 :         while (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME && !rhs[3])
    4978                 :             :           {
    4979                 :      478185 :             gimple *g = SSA_NAME_DEF_STMT (rhs[i]);
    4980                 :      478185 :             if (has_single_use (rhs[i])
    4981                 :      249631 :                 && is_gimple_assign (g)
    4982                 :      712807 :                 && gimple_assign_rhs_code (g) == PLUS_EXPR)
    4983                 :             :               {
    4984                 :       45387 :                 rhs[i] = gimple_assign_rhs1 (g);
    4985                 :       45387 :                 if (rhs[2])
    4986                 :        9887 :                   rhs[3] = gimple_assign_rhs2 (g);
    4987                 :             :                 else
    4988                 :       35500 :                   rhs[2] = gimple_assign_rhs2 (g);
    4989                 :       45387 :                 temp_stmts.quick_push (g);
    4990                 :             :               }
    4991                 :             :             else
    4992                 :             :               break;
    4993                 :             :           }
    4994                 :             :       /* If there are just 3 addends or one minuend and two subtrahends,
    4995                 :             :          check for UADDC or USUBC being pattern recognized earlier.
    4996                 :             :          Say r = op1 + op2 + ovf1 + ovf2; where the (ovf1 + ovf2) part
    4997                 :             :          got pattern matched earlier as __imag__ .UADDC (arg1, arg2, arg3)
    4998                 :             :          etc.  */
    4999                 :     1320297 :       if (rhs[2] && !rhs[3])
    5000                 :             :         {
    5001                 :      283605 :           for (int i = (code == MINUS_EXPR ? 1 : 0); i < 3; ++i)
    5002                 :      165160 :             if (TREE_CODE (rhs[i]) == SSA_NAME)
    5003                 :             :               {
    5004                 :      129889 :                 gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
    5005                 :      129889 :                 im = uaddc_ne0 (im);
    5006                 :      129889 :                 if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
    5007                 :             :                   {
    5008                 :             :                     /* We found one of the 3 addends or 2 subtrahends to be
    5009                 :             :                        __imag__ of something, verify it is .UADDC/.USUBC.  */
    5010                 :         172 :                     tree rhs1 = gimple_assign_rhs1 (im);
    5011                 :         172 :                     gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
    5012                 :         172 :                     tree ovf_lhs = NULL_TREE;
    5013                 :         172 :                     tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
    5014                 :         190 :                     if (gimple_call_internal_p (ovf, code == PLUS_EXPR
    5015                 :             :                                                      ? IFN_ADD_OVERFLOW
    5016                 :             :                                                      : IFN_SUB_OVERFLOW))
    5017                 :             :                       {
    5018                 :             :                         /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
    5019                 :             :                            This is for the case of 2 chained .UADDC/.USUBC,
    5020                 :             :                            where the first one uses 0 carry-in and the second
    5021                 :             :                            one ignores the carry-out.
    5022                 :             :                            So, something like:
    5023                 :             :                            _16 = .ADD_OVERFLOW (_1, _2);
    5024                 :             :                            _17 = REALPART_EXPR <_16>;
    5025                 :             :                            _18 = IMAGPART_EXPR <_16>;
    5026                 :             :                            _15 = _3 + _4;
    5027                 :             :                            _12 = _15 + _18;
    5028                 :             :                            where the first 3 statements come from the lower
    5029                 :             :                            limb addition and the last 2 from the higher limb
    5030                 :             :                            which ignores carry-out.  */
    5031                 :         156 :                         ovf_lhs = gimple_call_lhs (ovf);
    5032                 :         156 :                         tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
    5033                 :         156 :                         ovf_arg1 = gimple_call_arg (ovf, 0);
    5034                 :         156 :                         ovf_arg2 = gimple_call_arg (ovf, 1);
    5035                 :             :                         /* In that case we need to punt if the types don't
    5036                 :             :                            mismatch.  */
    5037                 :         156 :                         if (!types_compatible_p (type, ovf_lhs_type)
    5038                 :         156 :                             || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
    5039                 :         308 :                             || !types_compatible_p (type,
    5040                 :         152 :                                                     TREE_TYPE (ovf_arg2)))
    5041                 :             :                           ovf_lhs = NULL_TREE;
    5042                 :             :                         else
    5043                 :             :                           {
    5044                 :         371 :                             for (int i = (code == PLUS_EXPR ? 1 : 0);
    5045                 :         371 :                                  i >= 0; --i)
    5046                 :             :                               {
    5047                 :         265 :                                 tree r = gimple_call_arg (ovf, i);
    5048                 :         265 :                                 if (TREE_CODE (r) != SSA_NAME)
    5049                 :           0 :                                   continue;
    5050                 :         265 :                                 if (uaddc_is_cplxpart (SSA_NAME_DEF_STMT (r),
    5051                 :             :                                                        REALPART_EXPR))
    5052                 :             :                                   {
    5053                 :             :                                     /* Punt if one of the args which isn't
    5054                 :             :                                        subtracted isn't __real__; that could
    5055                 :             :                                        then prevent better match later.
    5056                 :             :                                        Consider:
    5057                 :             :                                        _3 = .ADD_OVERFLOW (_1, _2);
    5058                 :             :                                        _4 = REALPART_EXPR <_3>;
    5059                 :             :                                        _5 = IMAGPART_EXPR <_3>;
    5060                 :             :                                        _7 = .ADD_OVERFLOW (_4, _6);
    5061                 :             :                                        _8 = REALPART_EXPR <_7>;
    5062                 :             :                                        _9 = IMAGPART_EXPR <_7>;
    5063                 :             :                                        _12 = _10 + _11;
    5064                 :             :                                        _13 = _12 + _9;
    5065                 :             :                                        _14 = _13 + _5;
    5066                 :             :                                        We want to match this when called on
    5067                 :             :                                        the last stmt as a pair of .UADDC calls,
    5068                 :             :                                        but without this check we could turn
    5069                 :             :                                        that prematurely on _13 = _12 + _9;
    5070                 :             :                                        stmt into .UADDC with 0 carry-in just
    5071                 :             :                                        on the second .ADD_OVERFLOW call and
    5072                 :             :                                        another replacing the _12 and _13
    5073                 :             :                                        additions.  */
    5074                 :             :                                     ovf_lhs = NULL_TREE;
    5075                 :             :                                     break;
    5076                 :             :                                   }
    5077                 :             :                               }
    5078                 :             :                           }
    5079                 :         149 :                         if (ovf_lhs)
    5080                 :             :                           {
    5081                 :         106 :                             use_operand_p use_p;
    5082                 :         106 :                             imm_use_iterator iter;
    5083                 :         106 :                             tree re_lhs = NULL_TREE;
    5084                 :         318 :                             FOR_EACH_IMM_USE_FAST (use_p, iter, ovf_lhs)
    5085                 :             :                               {
    5086                 :         212 :                                 gimple *use_stmt = USE_STMT (use_p);
    5087                 :         212 :                                 if (is_gimple_debug (use_stmt))
    5088                 :           0 :                                   continue;
    5089                 :         212 :                                 if (use_stmt == im)
    5090                 :         106 :                                   continue;
    5091                 :         106 :                                 if (!uaddc_is_cplxpart (use_stmt,
    5092                 :             :                                                         REALPART_EXPR))
    5093                 :             :                                   {
    5094                 :             :                                     ovf_lhs = NULL_TREE;
    5095                 :             :                                     break;
    5096                 :             :                                   }
    5097                 :         106 :                                 re_lhs = gimple_assign_lhs (use_stmt);
    5098                 :             :                               }
    5099                 :         106 :                             if (ovf_lhs && re_lhs)
    5100                 :             :                               {
    5101                 :         213 :                                 FOR_EACH_IMM_USE_FAST (use_p, iter, re_lhs)
    5102                 :             :                                   {
    5103                 :         161 :                                     gimple *use_stmt = USE_STMT (use_p);
    5104                 :         161 :                                     if (is_gimple_debug (use_stmt))
    5105                 :          33 :                                       continue;
    5106                 :         128 :                                     internal_fn ifn
    5107                 :         128 :                                       = gimple_call_internal_fn (ovf);
    5108                 :             :                                     /* Punt if the __real__ of lhs is used
    5109                 :             :                                        in the same .*_OVERFLOW call.
    5110                 :             :                                        Consider:
    5111                 :             :                                        _3 = .ADD_OVERFLOW (_1, _2);
    5112                 :             :                                        _4 = REALPART_EXPR <_3>;
    5113                 :             :                                        _5 = IMAGPART_EXPR <_3>;
    5114                 :             :                                        _7 = .ADD_OVERFLOW (_4, _6);
    5115                 :             :                                        _8 = REALPART_EXPR <_7>;
    5116                 :             :                                        _9 = IMAGPART_EXPR <_7>;
    5117                 :             :                                        _12 = _10 + _11;
    5118                 :             :                                        _13 = _12 + _5;
    5119                 :             :                                        _14 = _13 + _9;
    5120                 :             :                                        We want to match this when called on
    5121                 :             :                                        the last stmt as a pair of .UADDC calls,
    5122                 :             :                                        but without this check we could turn
    5123                 :             :                                        that prematurely on _13 = _12 + _5;
    5124                 :             :                                        stmt into .UADDC with 0 carry-in just
    5125                 :             :                                        on the first .ADD_OVERFLOW call and
    5126                 :             :                                        another replacing the _12 and _13
    5127                 :             :                                        additions.  */
    5128                 :         128 :                                     if (gimple_call_internal_p (use_stmt, ifn))
    5129                 :             :                                       {
    5130                 :             :                                         ovf_lhs = NULL_TREE;
    5131                 :             :                                         break;
    5132                 :             :                                       }
    5133                 :             :                                   }
    5134                 :             :                               }
    5135                 :             :                           }
    5136                 :             :                       }
    5137                 :         106 :                     if ((ovf_lhs
    5138                 :         127 :                          || gimple_call_internal_p (ovf,
    5139                 :             :                                                     code == PLUS_EXPR
    5140                 :             :                                                     ? IFN_UADDC : IFN_USUBC))
    5141                 :         175 :                         && (optab_handler (code == PLUS_EXPR
    5142                 :             :                                            ? uaddc5_optab : usubc5_optab,
    5143                 :          56 :                                            TYPE_MODE (type))
    5144                 :             :                             != CODE_FOR_nothing))
    5145                 :             :                       {
    5146                 :             :                         /* And in that case build another .UADDC/.USUBC
    5147                 :             :                            call for the most significand limb addition.
    5148                 :             :                            Overflow bit is ignored here.  */
    5149                 :          49 :                         if (i != 2)
    5150                 :          49 :                           std::swap (rhs[i], rhs[2]);
    5151                 :          49 :                         gimple *g
    5152                 :          62 :                           = gimple_build_call_internal (code == PLUS_EXPR
    5153                 :             :                                                         ? IFN_UADDC
    5154                 :             :                                                         : IFN_USUBC,
    5155                 :             :                                                         3, rhs[0], rhs[1],
    5156                 :             :                                                         rhs[2]);
    5157                 :          49 :                         tree nlhs = make_ssa_name (build_complex_type (type));
    5158                 :          49 :                         gimple_call_set_lhs (g, nlhs);
    5159                 :          49 :                         gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5160                 :          49 :                         tree ilhs = gimple_assign_lhs (stmt);
    5161                 :          49 :                         g = gimple_build_assign (ilhs, REALPART_EXPR,
    5162                 :             :                                                  build1 (REALPART_EXPR,
    5163                 :          49 :                                                          TREE_TYPE (ilhs),
    5164                 :             :                                                          nlhs));
    5165                 :          49 :                         gsi_replace (gsi, g, true);
    5166                 :             :                         /* And if it is initialized from result of __imag__
    5167                 :             :                            of .{ADD,SUB}_OVERFLOW call, replace that
    5168                 :             :                            call with .U{ADD,SUB}C call with the same arguments,
    5169                 :             :                            just 0 added as third argument.  This isn't strictly
    5170                 :             :                            necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
    5171                 :             :                            produce the same result, but may result in better
    5172                 :             :                            generated code on some targets where the backend can
    5173                 :             :                            better prepare in how the result will be used.  */
    5174                 :          49 :                         if (ovf_lhs)
    5175                 :             :                           {
    5176                 :          45 :                             tree zero = build_zero_cst (type);
    5177                 :          45 :                             g = gimple_build_call_internal (code == PLUS_EXPR
    5178                 :             :                                                             ? IFN_UADDC
    5179                 :             :                                                             : IFN_USUBC,
    5180                 :             :                                                             3, ovf_arg1,
    5181                 :             :                                                             ovf_arg2, zero);
    5182                 :          45 :                             gimple_call_set_lhs (g, ovf_lhs);
    5183                 :          45 :                             gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf);
    5184                 :          45 :                             gsi_replace (&gsi2, g, true);
    5185                 :             :                           }
    5186                 :          49 :                         return true;
    5187                 :             :                       }
    5188                 :             :                   }
    5189                 :             :               }
    5190                 :             :           return false;
    5191                 :             :         }
    5192                 :     1261050 :       if (code == MINUS_EXPR && !rhs[2])
    5193                 :             :         return false;
    5194                 :         221 :       if (code == MINUS_EXPR)
    5195                 :             :         /* Code below expects rhs[0] and rhs[1] to have the IMAGPART_EXPRs.
    5196                 :             :            So, for MINUS_EXPR swap the single added rhs operand (others are
    5197                 :             :            subtracted) to rhs[3].  */
    5198                 :         221 :         std::swap (rhs[0], rhs[3]);
    5199                 :             :     }
    5200                 :             :   /* Walk from both operands of STMT (for +/- even sometimes from
    5201                 :             :      all the 4 addends or 3 subtrahends), see through casts and != 0
    5202                 :             :      statements which would preserve [0, 1] range of values and
    5203                 :             :      check which is initialized from __imag__.  */
    5204                 :     6650278 :   gimple *im1 = NULL, *im2 = NULL;
    5205                 :    13299673 :   for (int i = 0; i < (code == MINUS_EXPR ? 3 : 4); i++)
    5206                 :     5320340 :     if (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME)
    5207                 :             :       {
    5208                 :     1749320 :         gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
    5209                 :     1749320 :         im = uaddc_ne0 (im);
    5210                 :     1749320 :         if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
    5211                 :             :           {
    5212                 :        1444 :             if (im1 == NULL)
    5213                 :             :               {
    5214                 :        1053 :                 im1 = im;
    5215                 :        1053 :                 if (i != 0)
    5216                 :         278 :                   std::swap (rhs[0], rhs[i]);
    5217                 :             :               }
    5218                 :             :             else
    5219                 :             :               {
    5220                 :         391 :                 im2 = im;
    5221                 :         391 :                 if (i != 1)
    5222                 :          20 :                   std::swap (rhs[1], rhs[i]);
    5223                 :             :                 break;
    5224                 :             :               }
    5225                 :             :           }
    5226                 :             :       }
    5227                 :             :   /* If we don't find at least two, punt.  */
    5228                 :     1330329 :   if (!im2)
    5229                 :             :     return false;
    5230                 :             :   /* Check they are __imag__ of .ADD_OVERFLOW or .SUB_OVERFLOW call results,
    5231                 :             :      either both .ADD_OVERFLOW or both .SUB_OVERFLOW and that we have
    5232                 :             :      uaddc5/usubc5 named pattern for the corresponding mode.  */
    5233                 :         391 :   gimple *ovf1
    5234                 :         391 :     = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im1), 0));
    5235                 :         391 :   gimple *ovf2
    5236                 :         391 :     = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im2), 0));
    5237                 :         391 :   internal_fn ifn;
    5238                 :         391 :   if (!is_gimple_call (ovf1)
    5239                 :         391 :       || !gimple_call_internal_p (ovf1)
    5240                 :         391 :       || ((ifn = gimple_call_internal_fn (ovf1)) != IFN_ADD_OVERFLOW
    5241                 :          49 :           && ifn != IFN_SUB_OVERFLOW)
    5242                 :         368 :       || !gimple_call_internal_p (ovf2, ifn)
    5243                 :         386 :       || optab_handler (ifn == IFN_ADD_OVERFLOW ? uaddc5_optab : usubc5_optab,
    5244                 :         364 :                         TYPE_MODE (type)) == CODE_FOR_nothing
    5245                 :         459 :       || (rhs[2]
    5246                 :          13 :           && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
    5247                 :          12 :                             TYPE_MODE (type)) == CODE_FOR_nothing))
    5248                 :         323 :     return false;
    5249                 :          68 :   tree arg1, arg2, arg3 = NULL_TREE;
    5250                 :          68 :   gimple *re1 = NULL, *re2 = NULL;
    5251                 :             :   /* On one of the two calls, one of the .ADD_OVERFLOW/.SUB_OVERFLOW arguments
    5252                 :             :      should be initialized from __real__ of the other of the two calls.
    5253                 :             :      Though, for .SUB_OVERFLOW, it has to be the first argument, not the
    5254                 :             :      second one.  */
    5255                 :         250 :   for (int i = (ifn == IFN_ADD_OVERFLOW ? 1 : 0); i >= 0; --i)
    5256                 :         400 :     for (gimple *ovf = ovf1; ovf; ovf = (ovf == ovf1 ? ovf2 : NULL))
    5257                 :             :       {
    5258                 :         211 :         tree arg = gimple_call_arg (ovf, i);
    5259                 :         211 :         if (TREE_CODE (arg) != SSA_NAME)
    5260                 :           2 :           continue;
    5261                 :         209 :         re1 = SSA_NAME_DEF_STMT (arg);
    5262                 :         209 :         if (uaddc_is_cplxpart (re1, REALPART_EXPR)
    5263                 :         277 :             && (SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (re1), 0))
    5264                 :          68 :                 == (ovf == ovf1 ? ovf2 : ovf1)))
    5265                 :             :           {
    5266                 :          68 :             if (ovf == ovf1)
    5267                 :             :               {
    5268                 :             :                 /* Make sure ovf2 is the .*_OVERFLOW call with argument
    5269                 :             :                    initialized from __real__ of ovf1.  */
    5270                 :          17 :                 std::swap (rhs[0], rhs[1]);
    5271                 :          17 :                 std::swap (im1, im2);
    5272                 :          17 :                 std::swap (ovf1, ovf2);
    5273                 :             :               }
    5274                 :          68 :             arg3 = gimple_call_arg (ovf, 1 - i);
    5275                 :          68 :             i = -1;
    5276                 :          68 :             break;
    5277                 :             :           }
    5278                 :             :       }
    5279                 :          68 :   if (!arg3)
    5280                 :             :     return false;
    5281                 :          68 :   arg1 = gimple_call_arg (ovf1, 0);
    5282                 :          68 :   arg2 = gimple_call_arg (ovf1, 1);
    5283                 :          68 :   if (!types_compatible_p (type, TREE_TYPE (arg1)))
    5284                 :             :     return false;
    5285                 :          68 :   int kind[2] = { 0, 0 };
    5286                 :          68 :   tree arg_im[2] = { NULL_TREE, NULL_TREE };
    5287                 :             :   /* At least one of arg2 and arg3 should have type compatible
    5288                 :             :      with arg1/rhs[0], and the other one should have value in [0, 1]
    5289                 :             :      range.  If both are in [0, 1] range and type compatible with
    5290                 :             :      arg1/rhs[0], try harder to find after looking through casts,
    5291                 :             :      != 0 comparisons which one is initialized to __imag__ of
    5292                 :             :      .{ADD,SUB}_OVERFLOW or .U{ADD,SUB}C call results.  */
    5293                 :         204 :   for (int i = 0; i < 2; ++i)
    5294                 :             :     {
    5295                 :         136 :       tree arg = i == 0 ? arg2 : arg3;
    5296                 :         136 :       if (types_compatible_p (type, TREE_TYPE (arg)))
    5297                 :         121 :         kind[i] = 1;
    5298                 :         272 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (arg))
    5299                 :         272 :           || (TYPE_PRECISION (TREE_TYPE (arg)) == 1
    5300                 :          15 :               && !TYPE_UNSIGNED (TREE_TYPE (arg))))
    5301                 :           0 :         continue;
    5302                 :         136 :       if (tree_zero_one_valued_p (arg))
    5303                 :          35 :         kind[i] |= 2;
    5304                 :         136 :       if (TREE_CODE (arg) == SSA_NAME)
    5305                 :             :         {
    5306                 :         134 :           gimple *g = SSA_NAME_DEF_STMT (arg);
    5307                 :         134 :           if (gimple_assign_cast_p (g))
    5308                 :             :             {
    5309                 :          18 :               tree op = gimple_assign_rhs1 (g);
    5310                 :          18 :               if (TREE_CODE (op) == SSA_NAME
    5311                 :          18 :                   && INTEGRAL_TYPE_P (TREE_TYPE (op)))
    5312                 :          18 :                 g = SSA_NAME_DEF_STMT (op);
    5313                 :             :             }
    5314                 :         134 :           g = uaddc_ne0 (g);
    5315                 :         134 :           if (!uaddc_is_cplxpart (g, IMAGPART_EXPR))
    5316                 :          99 :             continue;
    5317                 :          35 :           arg_im[i] = gimple_assign_lhs (g);
    5318                 :          35 :           g = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (g), 0));
    5319                 :          35 :           if (!is_gimple_call (g) || !gimple_call_internal_p (g))
    5320                 :           0 :             continue;
    5321                 :          35 :           switch (gimple_call_internal_fn (g))
    5322                 :             :             {
    5323                 :          35 :             case IFN_ADD_OVERFLOW:
    5324                 :          35 :             case IFN_SUB_OVERFLOW:
    5325                 :          35 :             case IFN_UADDC:
    5326                 :          35 :             case IFN_USUBC:
    5327                 :          35 :               break;
    5328                 :           0 :             default:
    5329                 :           0 :               continue;
    5330                 :             :             }
    5331                 :          35 :           kind[i] |= 4;
    5332                 :             :         }
    5333                 :             :     }
    5334                 :             :   /* Make arg2 the one with compatible type and arg3 the one
    5335                 :             :      with [0, 1] range.  If both is true for both operands,
    5336                 :             :      prefer as arg3 result of __imag__ of some ifn.  */
    5337                 :          68 :   if ((kind[0] & 1) == 0 || ((kind[1] & 1) != 0 && kind[0] > kind[1]))
    5338                 :             :     {
    5339                 :           1 :       std::swap (arg2, arg3);
    5340                 :           1 :       std::swap (kind[0], kind[1]);
    5341                 :           1 :       std::swap (arg_im[0], arg_im[1]);
    5342                 :             :     }
    5343                 :          68 :   if ((kind[0] & 1) == 0 || (kind[1] & 6) == 0)
    5344                 :             :     return false;
    5345                 :          44 :   if (!has_single_use (gimple_assign_lhs (im1))
    5346                 :          42 :       || !has_single_use (gimple_assign_lhs (im2))
    5347                 :          42 :       || !has_single_use (gimple_assign_lhs (re1))
    5348                 :          86 :       || num_imm_uses (gimple_call_lhs (ovf1)) != 2)
    5349                 :             :     return false;
    5350                 :             :   /* Check that ovf2's result is used in __real__ and set re2
    5351                 :             :      to that statement.  */
    5352                 :          42 :   use_operand_p use_p;
    5353                 :          42 :   imm_use_iterator iter;
    5354                 :          42 :   tree lhs = gimple_call_lhs (ovf2);
    5355                 :         125 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    5356                 :             :     {
    5357                 :          83 :       gimple *use_stmt = USE_STMT (use_p);
    5358                 :          83 :       if (is_gimple_debug (use_stmt))
    5359                 :           0 :         continue;
    5360                 :          83 :       if (use_stmt == im2)
    5361                 :          42 :         continue;
    5362                 :          41 :       if (re2)
    5363                 :             :         return false;
    5364                 :          41 :       if (!uaddc_is_cplxpart (use_stmt, REALPART_EXPR))
    5365                 :             :         return false;
    5366                 :             :       re2 = use_stmt;
    5367                 :             :     }
    5368                 :             :   /* Build .UADDC/.USUBC call which will be placed before the stmt.  */
    5369                 :          42 :   gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf2);
    5370                 :          42 :   gimple *g;
    5371                 :          42 :   if ((kind[1] & 4) != 0 && types_compatible_p (type, TREE_TYPE (arg_im[1])))
    5372                 :             :     arg3 = arg_im[1];
    5373                 :          42 :   if ((kind[1] & 1) == 0)
    5374                 :             :     {
    5375                 :          15 :       if (TREE_CODE (arg3) == INTEGER_CST)
    5376                 :           0 :         arg3 = fold_convert (type, arg3);
    5377                 :             :       else
    5378                 :             :         {
    5379                 :          15 :           g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, arg3);
    5380                 :          15 :           gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
    5381                 :          15 :           arg3 = gimple_assign_lhs (g);
    5382                 :             :         }
    5383                 :             :     }
    5384                 :          54 :   g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
    5385                 :             :                                   ? IFN_UADDC : IFN_USUBC,
    5386                 :             :                                   3, arg1, arg2, arg3);
    5387                 :          42 :   tree nlhs = make_ssa_name (TREE_TYPE (lhs));
    5388                 :          42 :   gimple_call_set_lhs (g, nlhs);
    5389                 :          42 :   gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
    5390                 :             :   /* In the case where stmt is | or ^ of two overflow flags
    5391                 :             :      or addition of those, replace stmt with __imag__ of the above
    5392                 :             :      added call.  In case of arg1 + arg2 + (ovf1 + ovf2) or
    5393                 :             :      arg1 - arg2 - (ovf1 + ovf2) just emit it before stmt.  */
    5394                 :          42 :   tree ilhs = rhs[2] ? make_ssa_name (type) : gimple_assign_lhs (stmt);
    5395                 :          42 :   g = gimple_build_assign (ilhs, IMAGPART_EXPR,
    5396                 :          42 :                            build1 (IMAGPART_EXPR, TREE_TYPE (ilhs), nlhs));
    5397                 :          42 :   if (rhs[2])
    5398                 :             :     {
    5399                 :          12 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5400                 :             :       /* Remove some further statements which can't be kept in the IL because
    5401                 :             :          they can use SSA_NAMEs whose setter is going to be removed too.  */
    5402                 :          60 :       for (gimple *g2 : temp_stmts)
    5403                 :             :         {
    5404                 :          24 :           gsi2 = gsi_for_stmt (g2);
    5405                 :          24 :           gsi_remove (&gsi2, true);
    5406                 :          24 :           release_defs (g2);
    5407                 :             :         }
    5408                 :             :     }
    5409                 :             :   else
    5410                 :          30 :     gsi_replace (gsi, g, true);
    5411                 :             :   /* Remove some statements which can't be kept in the IL because they
    5412                 :             :      use SSA_NAME whose setter is going to be removed too.  */
    5413                 :          42 :   tree rhs1 = rhs[1];
    5414                 :          68 :   for (int i = 0; i < 2; i++)
    5415                 :          55 :     if (rhs1 == gimple_assign_lhs (im2))
    5416                 :             :       break;
    5417                 :             :     else
    5418                 :             :       {
    5419                 :          26 :         g = SSA_NAME_DEF_STMT (rhs1);
    5420                 :          26 :         rhs1 = gimple_assign_rhs1 (g);
    5421                 :          26 :         gsi2 = gsi_for_stmt (g);
    5422                 :          26 :         gsi_remove (&gsi2, true);
    5423                 :          26 :         release_defs (g);
    5424                 :             :       }
    5425                 :          42 :   gcc_checking_assert (rhs1 == gimple_assign_lhs (im2));
    5426                 :          42 :   gsi2 = gsi_for_stmt (im2);
    5427                 :          42 :   gsi_remove (&gsi2, true);
    5428                 :          42 :   release_defs (im2);
    5429                 :             :   /* Replace the re2 statement with __real__ of the newly added
    5430                 :             :      .UADDC/.USUBC call.  */
    5431                 :          42 :   if (re2)
    5432                 :             :     {
    5433                 :          41 :       gsi2 = gsi_for_stmt (re2);
    5434                 :          41 :       tree rlhs = gimple_assign_lhs (re2);
    5435                 :          41 :       g = gimple_build_assign (rlhs, REALPART_EXPR,
    5436                 :          41 :                                build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
    5437                 :          41 :       gsi_replace (&gsi2, g, true);
    5438                 :             :     }
    5439                 :          42 :   if (rhs[2])
    5440                 :             :     {
    5441                 :             :       /* If this is the arg1 + arg2 + (ovf1 + ovf2) or
    5442                 :             :          arg1 - arg2 - (ovf1 + ovf2) case for the most significant limb,
    5443                 :             :          replace stmt with __real__ of another .UADDC/.USUBC call which
    5444                 :             :          handles the most significant limb.  Overflow flag from this is
    5445                 :             :          ignored.  */
    5446                 :          13 :       g = gimple_build_call_internal (code == PLUS_EXPR
    5447                 :             :                                       ? IFN_UADDC : IFN_USUBC,
    5448                 :             :                                       3, rhs[3], rhs[2], ilhs);
    5449                 :          12 :       nlhs = make_ssa_name (TREE_TYPE (lhs));
    5450                 :          12 :       gimple_call_set_lhs (g, nlhs);
    5451                 :          12 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5452                 :          12 :       ilhs = gimple_assign_lhs (stmt);
    5453                 :          12 :       g = gimple_build_assign (ilhs, REALPART_EXPR,
    5454                 :          12 :                                build1 (REALPART_EXPR, TREE_TYPE (ilhs), nlhs));
    5455                 :          12 :       gsi_replace (gsi, g, true);
    5456                 :             :     }
    5457                 :          42 :   if (TREE_CODE (arg3) == SSA_NAME)
    5458                 :             :     {
    5459                 :             :       /* When pattern recognizing the second least significant limb
    5460                 :             :          above (i.e. first pair of .{ADD,SUB}_OVERFLOW calls for one limb),
    5461                 :             :          check if the [0, 1] range argument (i.e. carry in) isn't the
    5462                 :             :          result of another .{ADD,SUB}_OVERFLOW call (one handling the
    5463                 :             :          least significant limb).  Again look through casts and != 0.  */
    5464                 :          42 :       gimple *im3 = SSA_NAME_DEF_STMT (arg3);
    5465                 :          57 :       for (int i = 0; i < 2; ++i)
    5466                 :             :         {
    5467                 :          57 :           gimple *im4 = uaddc_cast (im3);
    5468                 :          57 :           if (im4 == im3)
    5469                 :             :             break;
    5470                 :             :           else
    5471                 :          15 :             im3 = im4;
    5472                 :             :         }
    5473                 :          42 :       im3 = uaddc_ne0 (im3);
    5474                 :          42 :       if (uaddc_is_cplxpart (im3, IMAGPART_EXPR))
    5475                 :             :         {
    5476                 :          35 :           gimple *ovf3
    5477                 :          35 :             = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
    5478                 :          35 :           if (gimple_call_internal_p (ovf3, ifn))
    5479                 :             :             {
    5480                 :          15 :               lhs = gimple_call_lhs (ovf3);
    5481                 :          15 :               arg1 = gimple_call_arg (ovf3, 0);
    5482                 :          15 :               arg2 = gimple_call_arg (ovf3, 1);
    5483                 :          15 :               if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
    5484                 :          15 :                   && types_compatible_p (type, TREE_TYPE (arg1))
    5485                 :          30 :                   && types_compatible_p (type, TREE_TYPE (arg2)))
    5486                 :             :                 {
    5487                 :             :                   /* And if it is initialized from result of __imag__
    5488                 :             :                      of .{ADD,SUB}_OVERFLOW call, replace that
    5489                 :             :                      call with .U{ADD,SUB}C call with the same arguments,
    5490                 :             :                      just 0 added as third argument.  This isn't strictly
    5491                 :             :                      necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
    5492                 :             :                      produce the same result, but may result in better
    5493                 :             :                      generated code on some targets where the backend can
    5494                 :             :                      better prepare in how the result will be used.  */
    5495                 :          15 :                   g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
    5496                 :             :                                                   ? IFN_UADDC : IFN_USUBC,
    5497                 :             :                                                   3, arg1, arg2,
    5498                 :             :                                                   build_zero_cst (type));
    5499                 :          15 :                   gimple_call_set_lhs (g, lhs);
    5500                 :          15 :                   gsi2 = gsi_for_stmt (ovf3);
    5501                 :          15 :                   gsi_replace (&gsi2, g, true);
    5502                 :             :                 }
    5503                 :             :             }
    5504                 :             :         }
    5505                 :             :     }
    5506                 :             :   return true;
    5507                 :     1484899 : }
    5508                 :             : 
    5509                 :             : /* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
    5510                 :             :    (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
    5511                 :             :    isn't a direct optab.  Also handle `<=`/`>` to be
    5512                 :             :    `x & (x - 1) !=/== x`. */
    5513                 :             : 
    5514                 :             : static void
    5515                 :     4102290 : match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
    5516                 :             : {
    5517                 :     4102290 :   tree clhs, crhs;
    5518                 :     4102290 :   enum tree_code code;
    5519                 :     4102290 :   bool was_le = false;
    5520                 :     4102290 :   if (gimple_code (stmt) == GIMPLE_COND)
    5521                 :             :     {
    5522                 :     3816653 :       clhs = gimple_cond_lhs (stmt);
    5523                 :     3816653 :       crhs = gimple_cond_rhs (stmt);
    5524                 :     3816653 :       code = gimple_cond_code (stmt);
    5525                 :             :     }
    5526                 :             :   else
    5527                 :             :     {
    5528                 :      285637 :       clhs = gimple_assign_rhs1 (stmt);
    5529                 :      285637 :       crhs = gimple_assign_rhs2 (stmt);
    5530                 :      285637 :       code = gimple_assign_rhs_code (stmt);
    5531                 :             :     }
    5532                 :     4102290 :   if (code != LE_EXPR && code != GT_EXPR
    5533                 :     4102290 :       && code != EQ_EXPR && code != NE_EXPR)
    5534                 :     4102284 :     return;
    5535                 :     1865495 :   if (code == LE_EXPR || code == GT_EXPR)
    5536                 :     3868174 :     was_le = true;
    5537                 :     3868174 :   if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
    5538                 :     3728736 :     return;
    5539                 :      139438 :   gimple *call = SSA_NAME_DEF_STMT (clhs);
    5540                 :      139438 :   combined_fn cfn = gimple_call_combined_fn (call);
    5541                 :      139438 :   switch (cfn)
    5542                 :             :     {
    5543                 :           7 :     CASE_CFN_POPCOUNT:
    5544                 :           7 :       break;
    5545                 :             :     default:
    5546                 :             :       return;
    5547                 :             :     }
    5548                 :           7 :   if (!has_single_use (clhs))
    5549                 :             :     return;
    5550                 :           6 :   tree arg = gimple_call_arg (call, 0);
    5551                 :           6 :   tree type = TREE_TYPE (arg);
    5552                 :           6 :   if (!INTEGRAL_TYPE_P (type))
    5553                 :             :     return;
    5554                 :           6 :   bool nonzero_arg = tree_expr_nonzero_p (arg);
    5555                 :           6 :   if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
    5556                 :             :     {
    5557                 :             :       /* Tell expand_POPCOUNT the popcount result is only used in equality
    5558                 :             :          comparison with one, so that it can decide based on rtx costs.  */
    5559                 :           0 :       gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
    5560                 :             :                                               was_le ? integer_minus_one_node
    5561                 :           0 :                                               : (nonzero_arg ? integer_zero_node
    5562                 :             :                                                  : integer_one_node));
    5563                 :           0 :       gimple_call_set_lhs (g, gimple_call_lhs (call));
    5564                 :           0 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    5565                 :           0 :       gsi_replace (&gsi2, g, true);
    5566                 :           0 :       return;
    5567                 :             :     }
    5568                 :           6 :   tree argm1 = make_ssa_name (type);
    5569                 :           6 :   gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
    5570                 :           6 :                                    build_int_cst (type, -1));
    5571                 :           6 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5572                 :           6 :   g = gimple_build_assign (make_ssa_name (type),
    5573                 :           6 :                            (nonzero_arg || was_le) ? BIT_AND_EXPR : BIT_XOR_EXPR,
    5574                 :             :                            arg, argm1);
    5575                 :           6 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5576                 :           6 :   tree_code cmpcode;
    5577                 :           6 :   if (was_le)
    5578                 :             :     {
    5579                 :           0 :       argm1 = build_zero_cst (type);
    5580                 :           0 :       cmpcode = code == LE_EXPR ? EQ_EXPR : NE_EXPR;
    5581                 :             :     }
    5582                 :           6 :   else if (nonzero_arg)
    5583                 :             :     {
    5584                 :           2 :       argm1 = build_zero_cst (type);
    5585                 :           2 :       cmpcode = code;
    5586                 :             :     }
    5587                 :             :   else
    5588                 :           4 :     cmpcode = code == EQ_EXPR ? GT_EXPR : LE_EXPR;
    5589                 :           6 :   if (gcond *cond = dyn_cast <gcond *> (stmt))
    5590                 :             :     {
    5591                 :           2 :       gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
    5592                 :           2 :       gimple_cond_set_rhs (cond, argm1);
    5593                 :           2 :       gimple_cond_set_code (cond, cmpcode);
    5594                 :             :     }
    5595                 :             :   else
    5596                 :             :     {
    5597                 :           4 :       gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
    5598                 :           4 :       gimple_assign_set_rhs2 (stmt, argm1);
    5599                 :           4 :       gimple_assign_set_rhs_code (stmt, cmpcode);
    5600                 :             :     }
    5601                 :           6 :   update_stmt (stmt);
    5602                 :           6 :   gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    5603                 :           6 :   gsi_remove (&gsi2, true);
    5604                 :           6 :   release_defs (call);
    5605                 :             : }
    5606                 :             : 
    5607                 :             : /* Return true if target has support for divmod.  */
    5608                 :             : 
    5609                 :             : static bool
    5610                 :       26205 : target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
    5611                 :             : {
    5612                 :             :   /* If target supports hardware divmod insn, use it for divmod.  */
    5613                 :       26205 :   if (optab_handler (divmod_optab, mode) != CODE_FOR_nothing)
    5614                 :             :     return true;
    5615                 :             : 
    5616                 :             :   /* Check if libfunc for divmod is available.  */
    5617                 :        2658 :   rtx libfunc = optab_libfunc (divmod_optab, mode);
    5618                 :        2658 :   if (libfunc != NULL_RTX)
    5619                 :             :     {
    5620                 :             :       /* If optab_handler exists for div_optab, perhaps in a wider mode,
    5621                 :             :          we don't want to use the libfunc even if it exists for given mode.  */
    5622                 :             :       machine_mode div_mode;
    5623                 :       11063 :       FOR_EACH_MODE_FROM (div_mode, mode)
    5624                 :        8405 :         if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
    5625                 :             :           return false;
    5626                 :             : 
    5627                 :        2658 :       return targetm.expand_divmod_libfunc != NULL;
    5628                 :             :     }
    5629                 :             : 
    5630                 :             :   return false;
    5631                 :             : }
    5632                 :             : 
    5633                 :             : /* Check if stmt is candidate for divmod transform.  */
    5634                 :             : 
    5635                 :             : static bool
    5636                 :       46323 : divmod_candidate_p (gassign *stmt)
    5637                 :             : {
    5638                 :       46323 :   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
    5639                 :       46323 :   machine_mode mode = TYPE_MODE (type);
    5640                 :       46323 :   optab divmod_optab, div_optab;
    5641                 :             : 
    5642                 :       46323 :   if (TYPE_UNSIGNED (type))
    5643                 :             :     {
    5644                 :             :       divmod_optab = udivmod_optab;
    5645                 :             :       div_optab = udiv_optab;
    5646                 :             :     }
    5647                 :             :   else
    5648                 :             :     {
    5649                 :       19601 :       divmod_optab = sdivmod_optab;
    5650                 :       19601 :       div_optab = sdiv_optab;
    5651                 :             :     }
    5652                 :             : 
    5653                 :       46323 :   tree op1 = gimple_assign_rhs1 (stmt);
    5654                 :       46323 :   tree op2 = gimple_assign_rhs2 (stmt);
    5655                 :             : 
    5656                 :             :   /* Disable the transform if either is a constant, since division-by-constant
    5657                 :             :      may have specialized expansion.  */
    5658                 :       46323 :   if (CONSTANT_CLASS_P (op1))
    5659                 :             :     return false;
    5660                 :             : 
    5661                 :       42732 :   if (CONSTANT_CLASS_P (op2))
    5662                 :             :     {
    5663                 :       18837 :       if (integer_pow2p (op2))
    5664                 :             :         return false;
    5665                 :             : 
    5666                 :       16915 :       if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
    5667                 :       17994 :           && element_precision (type) <= BITS_PER_WORD)
    5668                 :             :         return false;
    5669                 :             : 
    5670                 :             :       /* If the divisor is not power of 2 and the precision wider than
    5671                 :             :          HWI, expand_divmod punts on that, so in that case it is better
    5672                 :             :          to use divmod optab or libfunc.  Similarly if choose_multiplier
    5673                 :             :          might need pre/post shifts of BITS_PER_WORD or more.  */
    5674                 :             :     }
    5675                 :             : 
    5676                 :             :   /* Exclude the case where TYPE_OVERFLOW_TRAPS (type) as that should
    5677                 :             :      expand using the [su]divv optabs.  */
    5678                 :       26205 :   if (TYPE_OVERFLOW_TRAPS (type))
    5679                 :             :     return false;
    5680                 :             : 
    5681                 :       26205 :   if (!target_supports_divmod_p (divmod_optab, div_optab, mode))
    5682                 :             :     return false;
    5683                 :             : 
    5684                 :             :   return true;
    5685                 :             : }
    5686                 :             : 
    5687                 :             : /* This function looks for:
    5688                 :             :    t1 = a TRUNC_DIV_EXPR b;
    5689                 :             :    t2 = a TRUNC_MOD_EXPR b;
    5690                 :             :    and transforms it to the following sequence:
    5691                 :             :    complex_tmp = DIVMOD (a, b);
    5692                 :             :    t1 = REALPART_EXPR(a);
    5693                 :             :    t2 = IMAGPART_EXPR(b);
    5694                 :             :    For conditions enabling the transform see divmod_candidate_p().
    5695                 :             : 
    5696                 :             :    The pass has three parts:
    5697                 :             :    1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
    5698                 :             :       other trunc_div_expr and trunc_mod_expr stmts.
    5699                 :             :    2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
    5700                 :             :       to stmts vector.
    5701                 :             :    3) Insert DIVMOD call just before top_stmt and update entries in
    5702                 :             :       stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
    5703                 :             :       IMAGPART_EXPR for mod).  */
    5704                 :             : 
    5705                 :             : static bool
    5706                 :       46346 : convert_to_divmod (gassign *stmt)
    5707                 :             : {
    5708                 :       46346 :   if (stmt_can_throw_internal (cfun, stmt)
    5709                 :       46346 :       || !divmod_candidate_p (stmt))
    5710                 :       20141 :     return false;
    5711                 :             : 
    5712                 :       26205 :   tree op1 = gimple_assign_rhs1 (stmt);
    5713                 :       26205 :   tree op2 = gimple_assign_rhs2 (stmt);
    5714                 :             : 
    5715                 :       26205 :   imm_use_iterator use_iter;
    5716                 :       26205 :   gimple *use_stmt;
    5717                 :       26205 :   auto_vec<gimple *> stmts;
    5718                 :             : 
    5719                 :       26205 :   gimple *top_stmt = stmt;
    5720                 :       26205 :   basic_block top_bb = gimple_bb (stmt);
    5721                 :             : 
    5722                 :             :   /* Part 1: Try to set top_stmt to "topmost" stmt that dominates
    5723                 :             :      at-least stmt and possibly other trunc_div/trunc_mod stmts
    5724                 :             :      having same operands as stmt.  */
    5725                 :             : 
    5726                 :      110348 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op1)
    5727                 :             :     {
    5728                 :       84143 :       if (is_gimple_assign (use_stmt)
    5729                 :       52695 :           && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
    5730                 :       41176 :               || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
    5731                 :       43930 :           && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0)
    5732                 :      127962 :           && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0))
    5733                 :             :         {
    5734                 :       37676 :           if (stmt_can_throw_internal (cfun, use_stmt))
    5735                 :           0 :             continue;
    5736                 :             : 
    5737                 :       37676 :           basic_block bb = gimple_bb (use_stmt);
    5738                 :             : 
    5739                 :       37676 :           if (bb == top_bb)
    5740                 :             :             {
    5741                 :       36927 :               if (gimple_uid (use_stmt) < gimple_uid (top_stmt))
    5742                 :        5158 :                 top_stmt = use_stmt;
    5743                 :             :             }
    5744                 :         749 :           else if (dominated_by_p (CDI_DOMINATORS, top_bb, bb))
    5745                 :             :             {
    5746                 :         182 :               top_bb = bb;
    5747                 :         182 :               top_stmt = use_stmt;
    5748                 :             :             }
    5749                 :             :         }
    5750                 :       26205 :     }
    5751                 :             : 
    5752                 :       26205 :   tree top_op1 = gimple_assign_rhs1 (top_stmt);
    5753                 :       26205 :   tree top_op2 = gimple_assign_rhs2 (top_stmt);
    5754                 :             : 
    5755                 :       26205 :   stmts.safe_push (top_stmt);
    5756                 :       26205 :   bool div_seen = (gimple_assign_rhs_code (top_stmt) == TRUNC_DIV_EXPR);
    5757                 :             : 
    5758                 :             :   /* Part 2: Add all trunc_div/trunc_mod statements domianted by top_bb
    5759                 :             :      to stmts vector. The 2nd loop will always add stmt to stmts vector, since
    5760                 :             :      gimple_bb (top_stmt) dominates gimple_bb (stmt), so the
    5761                 :             :      2nd loop ends up adding at-least single trunc_mod_expr stmt.  */
    5762                 :             : 
    5763                 :      110348 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, top_op1)
    5764                 :             :     {
    5765                 :       84143 :       if (is_gimple_assign (use_stmt)
    5766                 :       52695 :           && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
    5767                 :       41176 :               || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
    5768                 :       43930 :           && operand_equal_p (top_op1, gimple_assign_rhs1 (use_stmt), 0)
    5769                 :      127962 :           && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0))
    5770                 :             :         {
    5771                 :       64007 :           if (use_stmt == top_stmt
    5772                 :       11471 :               || stmt_can_throw_internal (cfun, use_stmt)
    5773                 :       49147 :               || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb))
    5774                 :       26331 :             continue;
    5775                 :             : 
    5776                 :       11345 :           stmts.safe_push (use_stmt);
    5777                 :       11345 :           if (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR)
    5778                 :       84143 :             div_seen = true;
    5779                 :             :         }
    5780                 :       26205 :     }
    5781                 :             : 
    5782                 :       26205 :   if (!div_seen)
    5783                 :             :     return false;
    5784                 :             : 
    5785                 :             :   /* Part 3: Create libcall to internal fn DIVMOD:
    5786                 :             :      divmod_tmp = DIVMOD (op1, op2).  */
    5787                 :             : 
    5788                 :       11317 :   gcall *call_stmt = gimple_build_call_internal (IFN_DIVMOD, 2, op1, op2);
    5789                 :       11317 :   tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
    5790                 :             :                                  call_stmt, "divmod_tmp");
    5791                 :       11317 :   gimple_call_set_lhs (call_stmt, res);
    5792                 :             :   /* We rejected throwing statements above.  */
    5793                 :       11317 :   gimple_call_set_nothrow (call_stmt, true);
    5794                 :             : 
    5795                 :             :   /* Insert the call before top_stmt.  */
    5796                 :       11317 :   gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
    5797                 :       11317 :   gsi_insert_before (&top_stmt_gsi, call_stmt, GSI_SAME_STMT);
    5798                 :             : 
    5799                 :       11317 :   widen_mul_stats.divmod_calls_inserted++;
    5800                 :             : 
    5801                 :             :   /* Update all statements in stmts vector:
    5802                 :             :      lhs = op1 TRUNC_DIV_EXPR op2 -> lhs = REALPART_EXPR<divmod_tmp>
    5803                 :             :      lhs = op1 TRUNC_MOD_EXPR op2 -> lhs = IMAGPART_EXPR<divmod_tmp>.  */
    5804                 :             : 
    5805                 :       60182 :   for (unsigned i = 0; stmts.iterate (i, &use_stmt); ++i)
    5806                 :             :     {
    5807                 :       22660 :       tree new_rhs;
    5808                 :             : 
    5809                 :       22660 :       switch (gimple_assign_rhs_code (use_stmt))
    5810                 :             :         {
    5811                 :       11327 :           case TRUNC_DIV_EXPR:
    5812                 :       11327 :             new_rhs = fold_build1 (REALPART_EXPR, TREE_TYPE (op1), res);
    5813                 :       11327 :             break;
    5814                 :             : 
    5815                 :       11333 :           case TRUNC_MOD_EXPR:
    5816                 :       11333 :             new_rhs = fold_build1 (IMAGPART_EXPR, TREE_TYPE (op1), res);
    5817                 :       11333 :             break;
    5818                 :             : 
    5819                 :           0 :           default:
    5820                 :           0 :             gcc_unreachable ();
    5821                 :             :         }
    5822                 :             : 
    5823                 :       22660 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    5824                 :       22660 :       gimple_assign_set_rhs_from_tree (&gsi, new_rhs);
    5825                 :       22660 :       update_stmt (use_stmt);
    5826                 :             :     }
    5827                 :             : 
    5828                 :             :   return true;
    5829                 :       26205 : }
    5830                 :             : 
    5831                 :             : /* Process a single gimple assignment STMT, which has a RSHIFT_EXPR as
    5832                 :             :    its rhs, and try to convert it into a MULT_HIGHPART_EXPR.  The return
    5833                 :             :    value is true iff we converted the statement.  */
    5834                 :             : 
    5835                 :             : static bool
    5836                 :      152411 : convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
    5837                 :             : {
    5838                 :      152411 :   tree lhs = gimple_assign_lhs (stmt);
    5839                 :      152411 :   tree stype = TREE_TYPE (lhs);
    5840                 :      152411 :   tree sarg0 = gimple_assign_rhs1 (stmt);
    5841                 :      152411 :   tree sarg1 = gimple_assign_rhs2 (stmt);
    5842                 :             : 
    5843                 :      152411 :   if (TREE_CODE (stype) != INTEGER_TYPE
    5844                 :      145952 :       || TREE_CODE (sarg1) != INTEGER_CST
    5845                 :      130983 :       || TREE_CODE (sarg0) != SSA_NAME
    5846                 :      130982 :       || !tree_fits_uhwi_p (sarg1)
    5847                 :      283393 :       || !has_single_use (sarg0))
    5848                 :             :     return false;
    5849                 :             : 
    5850                 :       36807 :   gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (sarg0));
    5851                 :       33886 :   if (!def)
    5852                 :             :     return false;
    5853                 :             : 
    5854                 :       33886 :   enum tree_code mcode = gimple_assign_rhs_code (def);
    5855                 :       33886 :   if (mcode == NOP_EXPR)
    5856                 :             :     {
    5857                 :        5681 :       tree tmp = gimple_assign_rhs1 (def);
    5858                 :        5681 :       if (TREE_CODE (tmp) != SSA_NAME || !has_single_use (tmp))
    5859                 :             :         return false;
    5860                 :      153560 :       def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (tmp));
    5861                 :        1988 :       if (!def)
    5862                 :             :         return false;
    5863                 :        2663 :       mcode = gimple_assign_rhs_code (def);
    5864                 :             :     }
    5865                 :             : 
    5866                 :       30193 :   if (mcode != WIDEN_MULT_EXPR
    5867                 :       30193 :       || gimple_bb (def) != gimple_bb (stmt))
    5868                 :             :     return false;
    5869                 :         840 :   tree mtype = TREE_TYPE (gimple_assign_lhs (def));
    5870                 :         840 :   if (TREE_CODE (mtype) != INTEGER_TYPE
    5871                 :         840 :       || TYPE_PRECISION (mtype) != TYPE_PRECISION (stype))
    5872                 :             :     return false;
    5873                 :             : 
    5874                 :         840 :   tree mop1 = gimple_assign_rhs1 (def);
    5875                 :         840 :   tree mop2 = gimple_assign_rhs2 (def);
    5876                 :         840 :   tree optype = TREE_TYPE (mop1);
    5877                 :         840 :   bool unsignedp = TYPE_UNSIGNED (optype);
    5878                 :         840 :   unsigned int prec = TYPE_PRECISION (optype);
    5879                 :             : 
    5880                 :         840 :   if (unsignedp != TYPE_UNSIGNED (mtype)
    5881                 :         840 :       || TYPE_PRECISION (mtype) != 2 * prec)
    5882                 :             :     return false;
    5883                 :             : 
    5884                 :         840 :   unsigned HOST_WIDE_INT bits = tree_to_uhwi (sarg1);
    5885                 :         840 :   if (bits < prec || bits >= 2 * prec)
    5886                 :             :     return false;
    5887                 :             : 
    5888                 :             :   /* For the time being, require operands to have the same sign.  */
    5889                 :         839 :   if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2)))
    5890                 :             :     return false;
    5891                 :             : 
    5892                 :         839 :   machine_mode mode = TYPE_MODE (optype);
    5893                 :         839 :   optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
    5894                 :         839 :   if (optab_handler (tab, mode) == CODE_FOR_nothing)
    5895                 :             :     return false;
    5896                 :             : 
    5897                 :         839 :   location_t loc = gimple_location (stmt);
    5898                 :         839 :   tree highpart1 = build_and_insert_binop (gsi, loc, "highparttmp",
    5899                 :             :                                            MULT_HIGHPART_EXPR, mop1, mop2);
    5900                 :         839 :   tree highpart2 = highpart1;
    5901                 :         839 :   tree ntype = optype;
    5902                 :             : 
    5903                 :         839 :   if (TYPE_UNSIGNED (stype) != TYPE_UNSIGNED (optype))
    5904                 :             :     {
    5905                 :          16 :       ntype = TYPE_UNSIGNED (stype) ? unsigned_type_for (optype)
    5906                 :           7 :                                     : signed_type_for (optype);
    5907                 :          16 :       highpart2 = build_and_insert_cast (gsi, loc, ntype, highpart1);
    5908                 :             :     }
    5909                 :         839 :   if (bits > prec)
    5910                 :          29 :     highpart2 = build_and_insert_binop (gsi, loc, "highparttmp",
    5911                 :             :                                         RSHIFT_EXPR, highpart2,
    5912                 :          29 :                                         build_int_cst (ntype, bits - prec));
    5913                 :             : 
    5914                 :         839 :   gassign *new_stmt = gimple_build_assign (lhs, NOP_EXPR, highpart2);
    5915                 :         839 :   gsi_replace (gsi, new_stmt, true);
    5916                 :             : 
    5917                 :         839 :   widen_mul_stats.highpart_mults_inserted++;
    5918                 :         839 :   return true;
    5919                 :             : }
    5920                 :             : 
    5921                 :             : /* If target has spaceship<MODE>3 expander, pattern recognize
    5922                 :             :    <bb 2> [local count: 1073741824]:
    5923                 :             :    if (a_2(D) == b_3(D))
    5924                 :             :      goto <bb 6>; [34.00%]
    5925                 :             :    else
    5926                 :             :      goto <bb 3>; [66.00%]
    5927                 :             : 
    5928                 :             :    <bb 3> [local count: 708669601]:
    5929                 :             :    if (a_2(D) < b_3(D))
    5930                 :             :      goto <bb 6>; [1.04%]
    5931                 :             :    else
    5932                 :             :      goto <bb 4>; [98.96%]
    5933                 :             : 
    5934                 :             :    <bb 4> [local count: 701299439]:
    5935                 :             :    if (a_2(D) > b_3(D))
    5936                 :             :      goto <bb 5>; [48.89%]
    5937                 :             :    else
    5938                 :             :      goto <bb 6>; [51.11%]
    5939                 :             : 
    5940                 :             :    <bb 5> [local count: 342865295]:
    5941                 :             : 
    5942                 :             :    <bb 6> [local count: 1073741824]:
    5943                 :             :    and turn it into:
    5944                 :             :    <bb 2> [local count: 1073741824]:
    5945                 :             :    _1 = .SPACESHIP (a_2(D), b_3(D), 0);
    5946                 :             :    if (_1 == 0)
    5947                 :             :      goto <bb 6>; [34.00%]
    5948                 :             :    else
    5949                 :             :      goto <bb 3>; [66.00%]
    5950                 :             : 
    5951                 :             :    <bb 3> [local count: 708669601]:
    5952                 :             :    if (_1 == -1)
    5953                 :             :      goto <bb 6>; [1.04%]
    5954                 :             :    else
    5955                 :             :      goto <bb 4>; [98.96%]
    5956                 :             : 
    5957                 :             :    <bb 4> [local count: 701299439]:
    5958                 :             :    if (_1 == 1)
    5959                 :             :      goto <bb 5>; [48.89%]
    5960                 :             :    else
    5961                 :             :      goto <bb 6>; [51.11%]
    5962                 :             : 
    5963                 :             :    <bb 5> [local count: 342865295]:
    5964                 :             : 
    5965                 :             :    <bb 6> [local count: 1073741824]:
    5966                 :             :    so that the backend can emit optimal comparison and
    5967                 :             :    conditional jump sequence.  If the
    5968                 :             :    <bb 6> [local count: 1073741824]:
    5969                 :             :    above has a single PHI like:
    5970                 :             :    # _27 = PHI<0(2), -1(3), 2(4), 1(5)>
    5971                 :             :    then replace it with effectively
    5972                 :             :    _1 = .SPACESHIP (a_2(D), b_3(D), 1);
    5973                 :             :    _27 = _1;  */
    5974                 :             : 
    5975                 :             : static void
    5976                 :     3816653 : optimize_spaceship (gcond *stmt)
    5977                 :             : {
    5978                 :     3816653 :   enum tree_code code = gimple_cond_code (stmt);
    5979                 :     3816653 :   if (code != EQ_EXPR && code != NE_EXPR)
    5980                 :     3816383 :     return;
    5981                 :     3110054 :   tree arg1 = gimple_cond_lhs (stmt);
    5982                 :     3110054 :   tree arg2 = gimple_cond_rhs (stmt);
    5983                 :     3110054 :   if ((!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1))
    5984                 :     3001798 :        && !INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
    5985                 :     2448928 :       || optab_handler (spaceship_optab,
    5986                 :     2448928 :                         TYPE_MODE (TREE_TYPE (arg1))) == CODE_FOR_nothing
    5987                 :     5519633 :       || operand_equal_p (arg1, arg2, 0))
    5988                 :      701532 :     return;
    5989                 :             : 
    5990                 :     2408522 :   basic_block bb0 = gimple_bb (stmt), bb1, bb2 = NULL;
    5991                 :     2408522 :   edge em1 = NULL, e1 = NULL, e2 = NULL;
    5992                 :     2408522 :   bb1 = EDGE_SUCC (bb0, 1)->dest;
    5993                 :     2408522 :   if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
    5994                 :     1460953 :     bb1 = EDGE_SUCC (bb0, 0)->dest;
    5995                 :             : 
    5996                 :     7083130 :   gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
    5997                 :     1015314 :   if (g == NULL
    5998                 :     1015314 :       || !single_pred_p (bb1)
    5999                 :      646915 :       || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6000                 :      547394 :           ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
    6001                 :      447873 :           : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
    6002                 :         879 :              || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
    6003                 :      558639 :       || !cond_only_block_p (bb1))
    6004                 :     2398031 :     return;
    6005                 :             : 
    6006                 :       10491 :   enum tree_code ccode = (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6007                 :       10491 :                           ? LT_EXPR : GT_EXPR);
    6008                 :       10491 :   switch (gimple_cond_code (g))
    6009                 :             :     {
    6010                 :             :     case LT_EXPR:
    6011                 :             :     case LE_EXPR:
    6012                 :             :       break;
    6013                 :        8671 :     case GT_EXPR:
    6014                 :        8671 :     case GE_EXPR:
    6015                 :        8671 :       ccode = ccode == LT_EXPR ? GT_EXPR : LT_EXPR;
    6016                 :             :       break;
    6017                 :             :     default:
    6018                 :             :       return;
    6019                 :             :     }
    6020                 :             : 
    6021                 :       31040 :   for (int i = 0; i < 2; ++i)
    6022                 :             :     {
    6023                 :             :       /* With NaNs, </<=/>/>= are false, so we need to look for the
    6024                 :             :          third comparison on the false edge from whatever non-equality
    6025                 :             :          comparison the second comparison is.  */
    6026                 :       20814 :       if (HONOR_NANS (TREE_TYPE (arg1))
    6027                 :       20814 :           && (EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0)
    6028                 :         277 :         continue;
    6029                 :             : 
    6030                 :       20537 :       bb2 = EDGE_SUCC (bb1, i)->dest;
    6031                 :       60957 :       g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
    6032                 :       14595 :       if (g == NULL
    6033                 :       14595 :           || !single_pred_p (bb2)
    6034                 :       20661 :           || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6035                 :       12136 :               ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
    6036                 :        3611 :               : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
    6037                 :          12 :                  || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
    6038                 :         184 :           || !cond_only_block_p (bb2)
    6039                 :       12320 :           || EDGE_SUCC (bb2, 0)->dest == EDGE_SUCC (bb2, 1)->dest)
    6040                 :       20353 :         continue;
    6041                 :             : 
    6042                 :         184 :       enum tree_code ccode2
    6043                 :         184 :         = (operand_equal_p (gimple_cond_lhs (g), arg1, 0) ? LT_EXPR : GT_EXPR);
    6044                 :         184 :       switch (gimple_cond_code (g))
    6045                 :             :         {
    6046                 :             :         case LT_EXPR:
    6047                 :             :         case LE_EXPR:
    6048                 :             :           break;
    6049                 :          83 :         case GT_EXPR:
    6050                 :          83 :         case GE_EXPR:
    6051                 :          83 :           ccode2 = ccode2 == LT_EXPR ? GT_EXPR : LT_EXPR;
    6052                 :             :           break;
    6053                 :           0 :         default:
    6054                 :           0 :           continue;
    6055                 :             :         }
    6056                 :         184 :       if (HONOR_NANS (TREE_TYPE (arg1)) && ccode == ccode2)
    6057                 :           0 :         continue;
    6058                 :             : 
    6059                 :         368 :       if ((ccode == LT_EXPR)
    6060                 :         184 :           ^ ((EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0))
    6061                 :             :         {
    6062                 :          83 :           em1 = EDGE_SUCC (bb1, 1 - i);
    6063                 :          83 :           e1 = EDGE_SUCC (bb2, 0);
    6064                 :          83 :           e2 = EDGE_SUCC (bb2, 1);
    6065                 :          83 :           if ((ccode2 == LT_EXPR) ^ ((e1->flags & EDGE_TRUE_VALUE) == 0))
    6066                 :           0 :             std::swap (e1, e2);
    6067                 :             :         }
    6068                 :             :       else
    6069                 :             :         {
    6070                 :         101 :           e1 = EDGE_SUCC (bb1, 1 - i);
    6071                 :         101 :           em1 = EDGE_SUCC (bb2, 0);
    6072                 :         101 :           e2 = EDGE_SUCC (bb2, 1);
    6073                 :         101 :           if ((ccode2 != LT_EXPR) ^ ((em1->flags & EDGE_TRUE_VALUE) == 0))
    6074                 :             :             std::swap (em1, e2);
    6075                 :             :         }
    6076                 :             :       break;
    6077                 :             :     }
    6078                 :             : 
    6079                 :       10309 :   if (em1 == NULL)
    6080                 :             :     {
    6081                 :       20452 :       if ((ccode == LT_EXPR)
    6082                 :       10226 :           ^ ((EDGE_SUCC (bb1, 0)->flags & EDGE_TRUE_VALUE) != 0))
    6083                 :             :         {
    6084                 :        2897 :           em1 = EDGE_SUCC (bb1, 1);
    6085                 :        2897 :           e1 = EDGE_SUCC (bb1, 0);
    6086                 :        2897 :           e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
    6087                 :             :         }
    6088                 :             :       else
    6089                 :             :         {
    6090                 :        7329 :           em1 = EDGE_SUCC (bb1, 0);
    6091                 :        7329 :           e1 = EDGE_SUCC (bb1, 1);
    6092                 :        7329 :           e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
    6093                 :             :         }
    6094                 :             :     }
    6095                 :             : 
    6096                 :             :   /* Check if there is a single bb into which all failed conditions
    6097                 :             :      jump to (perhaps through an empty block) and if it results in
    6098                 :             :      a single integral PHI which just sets it to -1, 0, 1, X
    6099                 :             :      (or -1, 0, 1 when NaNs can't happen).  In that case use 1 rather
    6100                 :             :      than 0 as last .SPACESHIP argument to tell backends it might
    6101                 :             :      consider different code generation and just cast the result
    6102                 :             :      of .SPACESHIP to the PHI result.  X above is some value
    6103                 :             :      other than -1, 0, 1, for libstdc++ 2, for libc++ -127.  */
    6104                 :       10410 :   tree arg3 = integer_zero_node;
    6105                 :       10410 :   edge e = EDGE_SUCC (bb0, 0);
    6106                 :       10410 :   if (e->dest == bb1)
    6107                 :        7588 :     e = EDGE_SUCC (bb0, 1);
    6108                 :       10410 :   basic_block bbp = e->dest;
    6109                 :       10410 :   gphi *phi = NULL;
    6110                 :       10410 :   for (gphi_iterator psi = gsi_start_phis (bbp);
    6111                 :       12892 :        !gsi_end_p (psi); gsi_next (&psi))
    6112                 :             :     {
    6113                 :        4116 :       gphi *gp = psi.phi ();
    6114                 :        4116 :       tree res = gimple_phi_result (gp);
    6115                 :             : 
    6116                 :        4116 :       if (phi != NULL
    6117                 :        3734 :           || virtual_operand_p (res)
    6118                 :        2700 :           || !INTEGRAL_TYPE_P (TREE_TYPE (res))
    6119                 :        6725 :           || TYPE_PRECISION (TREE_TYPE (res)) < 2)
    6120                 :             :         {
    6121                 :             :           phi = NULL;
    6122                 :             :           break;
    6123                 :             :         }
    6124                 :        2482 :       phi = gp;
    6125                 :             :     }
    6126                 :       10410 :   if (phi
    6127                 :        2100 :       && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
    6128                 :       10902 :       && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
    6129                 :             :     {
    6130                 :          97 :       HOST_WIDE_INT argval = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? 2 : -1;
    6131                 :         578 :       for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
    6132                 :             :         {
    6133                 :         210 :           edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
    6134                 :         210 :           if (e3->dest != bbp)
    6135                 :             :             {
    6136                 :          97 :               if (!empty_block_p (e3->dest)
    6137                 :          87 :                   || !single_succ_p (e3->dest)
    6138                 :         184 :                   || single_succ (e3->dest) != bbp)
    6139                 :             :                 {
    6140                 :             :                   phi = NULL;
    6141                 :             :                   break;
    6142                 :             :                 }
    6143                 :             :               e3 = single_succ_edge (e3->dest);
    6144                 :             :             }
    6145                 :         200 :           tree a = gimple_phi_arg_def_from_edge (phi, e3);
    6146                 :         200 :           if (TREE_CODE (a) != INTEGER_CST
    6147                 :         200 :               || (i == 0 && !integer_onep (a))
    6148                 :         396 :               || (i == 1 && !integer_all_onesp (a)))
    6149                 :             :             {
    6150                 :             :               phi = NULL;
    6151                 :             :               break;
    6152                 :             :             }
    6153                 :         196 :           if (i == 2)
    6154                 :             :             {
    6155                 :          30 :               tree minv = TYPE_MIN_VALUE (signed_char_type_node);
    6156                 :          30 :               tree maxv = TYPE_MAX_VALUE (signed_char_type_node);
    6157                 :          30 :               widest_int w = widest_int::from (wi::to_wide (a), SIGNED);
    6158                 :          59 :               if ((w >= -1 && w <= 1)
    6159                 :          26 :                   || w < wi::to_widest (minv)
    6160                 :          56 :                   || w > wi::to_widest (maxv))
    6161                 :             :                 {
    6162                 :           4 :                   phi = NULL;
    6163                 :           4 :                   break;
    6164                 :             :                 }
    6165                 :          26 :               argval = w.to_shwi ();
    6166                 :          26 :             }
    6167                 :             :         }
    6168                 :          97 :       if (phi)
    6169                 :          79 :         arg3 = build_int_cst (integer_type_node,
    6170                 :          91 :                               TYPE_UNSIGNED (TREE_TYPE (arg1)) ? 1 : argval);
    6171                 :             :     }
    6172                 :             : 
    6173                 :             :   /* For integral <=> comparisons only use .SPACESHIP if it is turned
    6174                 :             :      into an integer (-1, 0, 1).  */
    6175                 :       10410 :   if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) && arg3 == integer_zero_node)
    6176                 :             :     return;
    6177                 :             : 
    6178                 :         349 :   gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 3, arg1, arg2, arg3);
    6179                 :         349 :   tree lhs = make_ssa_name (integer_type_node);
    6180                 :         349 :   gimple_call_set_lhs (gc, lhs);
    6181                 :         349 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    6182                 :         349 :   gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
    6183                 :             : 
    6184                 :         619 :   wide_int wmin = wi::minus_one (TYPE_PRECISION (integer_type_node));
    6185                 :         619 :   wide_int wmax = wi::one (TYPE_PRECISION (integer_type_node));
    6186                 :         349 :   if (HONOR_NANS (TREE_TYPE (arg1)))
    6187                 :             :     {
    6188                 :         277 :       if (arg3 == integer_zero_node)
    6189                 :         251 :         wmax = wi::two (TYPE_PRECISION (integer_type_node));
    6190                 :          26 :       else if (tree_int_cst_sgn (arg3) < 0)
    6191                 :           1 :         wmin = wi::to_wide (arg3);
    6192                 :             :       else
    6193                 :          25 :         wmax = wi::to_wide (arg3);
    6194                 :             :     }
    6195                 :         619 :   int_range<1> vr (TREE_TYPE (lhs), wmin, wmax);
    6196                 :         349 :   set_range_info (lhs, vr);
    6197                 :             : 
    6198                 :         349 :   if (arg3 != integer_zero_node)
    6199                 :             :     {
    6200                 :          79 :       tree type = TREE_TYPE (gimple_phi_result (phi));
    6201                 :          79 :       if (!useless_type_conversion_p (type, integer_type_node))
    6202                 :             :         {
    6203                 :          55 :           tree tem = make_ssa_name (type);
    6204                 :          55 :           gimple *gcv = gimple_build_assign (tem, NOP_EXPR, lhs);
    6205                 :          55 :           gsi_insert_before (&gsi, gcv, GSI_SAME_STMT);
    6206                 :          55 :           lhs = tem;
    6207                 :             :         }
    6208                 :          79 :       SET_PHI_ARG_DEF_ON_EDGE (phi, e, lhs);
    6209                 :          79 :       gimple_cond_set_lhs (stmt, boolean_false_node);
    6210                 :          79 :       gimple_cond_set_rhs (stmt, boolean_false_node);
    6211                 :          79 :       gimple_cond_set_code (stmt, (e->flags & EDGE_TRUE_VALUE)
    6212                 :             :                                   ? EQ_EXPR : NE_EXPR);
    6213                 :          79 :       update_stmt (stmt);
    6214                 :          79 :       return;
    6215                 :             :     }
    6216                 :             : 
    6217                 :         270 :   gimple_cond_set_lhs (stmt, lhs);
    6218                 :         270 :   gimple_cond_set_rhs (stmt, integer_zero_node);
    6219                 :         270 :   update_stmt (stmt);
    6220                 :             : 
    6221                 :         540 :   gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
    6222                 :         270 :   gimple_cond_set_lhs (cond, lhs);
    6223                 :         270 :   if (em1->src == bb1 && e2 != em1)
    6224                 :             :     {
    6225                 :         121 :       gimple_cond_set_rhs (cond, integer_minus_one_node);
    6226                 :         127 :       gimple_cond_set_code (cond, (em1->flags & EDGE_TRUE_VALUE)
    6227                 :             :                                   ? EQ_EXPR : NE_EXPR);
    6228                 :             :     }
    6229                 :             :   else
    6230                 :             :     {
    6231                 :         149 :       gcc_assert (e1->src == bb1 && e2 != e1);
    6232                 :         149 :       gimple_cond_set_rhs (cond, integer_one_node);
    6233                 :         149 :       gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
    6234                 :             :                                   ? EQ_EXPR : NE_EXPR);
    6235                 :             :     }
    6236                 :         270 :   update_stmt (cond);
    6237                 :             : 
    6238                 :         270 :   if (e2 != e1 && e2 != em1)
    6239                 :             :     {
    6240                 :         316 :       cond = as_a <gcond *> (*gsi_last_bb (bb2));
    6241                 :         158 :       gimple_cond_set_lhs (cond, lhs);
    6242                 :         158 :       if (em1->src == bb2)
    6243                 :         101 :         gimple_cond_set_rhs (cond, integer_minus_one_node);
    6244                 :             :       else
    6245                 :             :         {
    6246                 :          57 :           gcc_assert (e1->src == bb2);
    6247                 :          57 :           gimple_cond_set_rhs (cond, integer_one_node);
    6248                 :             :         }
    6249                 :         316 :       gimple_cond_set_code (cond,
    6250                 :         158 :                             (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
    6251                 :         158 :       update_stmt (cond);
    6252                 :             :     }
    6253                 :             : }
    6254                 :             : 
    6255                 :             : 
    6256                 :             : /* Find integer multiplications where the operands are extended from
    6257                 :             :    smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
    6258                 :             :    or MULT_HIGHPART_EXPR where appropriate.  */
    6259                 :             : 
    6260                 :             : namespace {
    6261                 :             : 
    6262                 :             : const pass_data pass_data_optimize_widening_mul =
    6263                 :             : {
    6264                 :             :   GIMPLE_PASS, /* type */
    6265                 :             :   "widening_mul", /* name */
    6266                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    6267                 :             :   TV_TREE_WIDEN_MUL, /* tv_id */
    6268                 :             :   PROP_ssa, /* properties_required */
    6269                 :             :   0, /* properties_provided */
    6270                 :             :   0, /* properties_destroyed */
    6271                 :             :   0, /* todo_flags_start */
    6272                 :             :   TODO_update_ssa, /* todo_flags_finish */
    6273                 :             : };
    6274                 :             : 
    6275                 :             : class pass_optimize_widening_mul : public gimple_opt_pass
    6276                 :             : {
    6277                 :             : public:
    6278                 :      282866 :   pass_optimize_widening_mul (gcc::context *ctxt)
    6279                 :      565732 :     : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt)
    6280                 :             :   {}
    6281                 :             : 
    6282                 :             :   /* opt_pass methods: */
    6283                 :     1000974 :   bool gate (function *) final override
    6284                 :             :     {
    6285                 :     1000974 :       return flag_expensive_optimizations && optimize;
    6286                 :             :     }
    6287                 :             : 
    6288                 :             :   unsigned int execute (function *) final override;
    6289                 :             : 
    6290                 :             : }; // class pass_optimize_widening_mul
    6291                 :             : 
    6292                 :             : /* Walker class to perform the transformation in reverse dominance order. */
    6293                 :             : 
    6294                 :             : class math_opts_dom_walker : public dom_walker
    6295                 :             : {
    6296                 :             : public:
    6297                 :             :   /* Constructor, CFG_CHANGED is a pointer to a boolean flag that will be set
    6298                 :             :      if walking modidifes the CFG.  */
    6299                 :             : 
    6300                 :      927944 :   math_opts_dom_walker (bool *cfg_changed_p)
    6301                 :     2783832 :     : dom_walker (CDI_DOMINATORS), m_last_result_set (),
    6302                 :      927944 :       m_cfg_changed_p (cfg_changed_p) {}
    6303                 :             : 
    6304                 :             :   /* The actual actions performed in the walk.  */
    6305                 :             : 
    6306                 :             :   void after_dom_children (basic_block) final override;
    6307                 :             : 
    6308                 :             :   /* Set of results of chains of multiply and add statement combinations that
    6309                 :             :      were not transformed into FMAs because of active deferring.  */
    6310                 :             :   hash_set<tree> m_last_result_set;
    6311                 :             : 
    6312                 :             :   /* Pointer to a flag of the user that needs to be set if CFG has been
    6313                 :             :      modified.  */
    6314                 :             :   bool *m_cfg_changed_p;
    6315                 :             : };
    6316                 :             : 
    6317                 :             : void
    6318                 :     9836340 : math_opts_dom_walker::after_dom_children (basic_block bb)
    6319                 :             : {
    6320                 :     9836340 :   gimple_stmt_iterator gsi;
    6321                 :             : 
    6322                 :     9836340 :   fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
    6323                 :             : 
    6324                 :    13923398 :   for (gphi_iterator psi_next, psi = gsi_start_phis (bb); !gsi_end_p (psi);
    6325                 :     4087058 :        psi = psi_next)
    6326                 :             :     {
    6327                 :     4087058 :       psi_next = psi;
    6328                 :     4087058 :       gsi_next (&psi_next);
    6329                 :             : 
    6330                 :     4087058 :       gimple_stmt_iterator gsi = gsi_after_labels (bb);
    6331                 :     4087058 :       gphi *phi = psi.phi ();
    6332                 :             : 
    6333                 :     4087058 :       if (match_saturation_add (&gsi, phi)
    6334                 :     4087041 :           || match_saturation_sub (&gsi, phi)
    6335                 :     8174083 :           || match_saturation_trunc (&gsi, phi))
    6336                 :          33 :         remove_phi_node (&psi, /* release_lhs_p */ false);
    6337                 :             :     }
    6338                 :             : 
    6339                 :    80144788 :   for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
    6340                 :             :     {
    6341                 :    70308448 :       gimple *stmt = gsi_stmt (gsi);
    6342                 :    70308448 :       enum tree_code code;
    6343                 :             : 
    6344                 :    70308448 :       if (is_gimple_assign (stmt))
    6345                 :             :         {
    6346                 :    19952950 :           code = gimple_assign_rhs_code (stmt);
    6347                 :    19952950 :           switch (code)
    6348                 :             :             {
    6349                 :      662934 :             case MULT_EXPR:
    6350                 :      662934 :               if (!convert_mult_to_widen (stmt, &gsi)
    6351                 :      652732 :                   && !convert_expand_mult_copysign (stmt, &gsi)
    6352                 :     1315620 :                   && convert_mult_to_fma (stmt,
    6353                 :             :                                           gimple_assign_rhs1 (stmt),
    6354                 :             :                                           gimple_assign_rhs2 (stmt),
    6355                 :             :                                           &fma_state))
    6356                 :             :                 {
    6357                 :       17224 :                   gsi_remove (&gsi, true);
    6358                 :       17224 :                   release_defs (stmt);
    6359                 :       17224 :                   continue;
    6360                 :             :                 }
    6361                 :      645710 :               match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
    6362                 :      645710 :               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
    6363                 :      645710 :               break;
    6364                 :             : 
    6365                 :     2110595 :             case PLUS_EXPR:
    6366                 :     2110595 :               match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
    6367                 :     2110595 :               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
    6368                 :             :               /* fall-through  */
    6369                 :     2380909 :             case MINUS_EXPR:
    6370                 :     2380909 :               if (!convert_plusminus_to_widen (&gsi, stmt, code))
    6371                 :             :                 {
    6372                 :     2380909 :                   match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
    6373                 :     2380909 :                   if (gsi_stmt (gsi) == stmt)
    6374                 :     2374706 :                     match_uaddc_usubc (&gsi, stmt, code);
    6375                 :             :                 }
    6376                 :             :               break;
    6377                 :             : 
    6378                 :       31642 :             case BIT_NOT_EXPR:
    6379                 :       31642 :               if (match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p))
    6380                 :         170 :                 continue;
    6381                 :             :               break;
    6382                 :             : 
    6383                 :       46346 :             case TRUNC_MOD_EXPR:
    6384                 :       46346 :               convert_to_divmod (as_a<gassign *> (stmt));
    6385                 :       46346 :               break;
    6386                 :             : 
    6387                 :      152411 :             case RSHIFT_EXPR:
    6388                 :      152411 :               convert_mult_to_highpart (as_a<gassign *> (stmt), &gsi);
    6389                 :      152411 :               break;
    6390                 :             : 
    6391                 :      187099 :             case BIT_IOR_EXPR:
    6392                 :      187099 :               match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
    6393                 :      187099 :               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
    6394                 :             :               /* fall-through  */
    6395                 :      213173 :             case BIT_XOR_EXPR:
    6396                 :      213173 :               match_uaddc_usubc (&gsi, stmt, code);
    6397                 :      213173 :               break;
    6398                 :             : 
    6399                 :      285637 :             case EQ_EXPR:
    6400                 :      285637 :             case NE_EXPR:
    6401                 :      285637 :             case LE_EXPR:
    6402                 :      285637 :             case GT_EXPR:
    6403                 :      285637 :               match_single_bit_test (&gsi, stmt);
    6404                 :      285637 :               break;
    6405                 :             : 
    6406                 :      365338 :             case COND_EXPR:
    6407                 :      365338 :             case BIT_AND_EXPR:
    6408                 :      365338 :               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
    6409                 :      365338 :               break;
    6410                 :             : 
    6411                 :     2306156 :             case NOP_EXPR:
    6412                 :     2306156 :               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
    6413                 :     2306156 :               break;
    6414                 :             : 
    6415                 :             :             default:;
    6416                 :             :             }
    6417                 :             :         }
    6418                 :    50355498 :       else if (is_gimple_call (stmt))
    6419                 :             :         {
    6420                 :     4533971 :           switch (gimple_call_combined_fn (stmt))
    6421                 :             :             {
    6422                 :         484 :             CASE_CFN_POW:
    6423                 :         484 :               if (gimple_call_lhs (stmt)
    6424                 :         445 :                   && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
    6425                 :         230 :                   && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
    6426                 :             :                                  &dconst2)
    6427                 :         484 :                   && convert_mult_to_fma (stmt,
    6428                 :             :                                           gimple_call_arg (stmt, 0),
    6429                 :             :                                           gimple_call_arg (stmt, 0),
    6430                 :             :                                           &fma_state))
    6431                 :             :                 {
    6432                 :           0 :                   unlink_stmt_vdef (stmt);
    6433                 :           0 :                   if (gsi_remove (&gsi, true)
    6434                 :           0 :                       && gimple_purge_dead_eh_edges (bb))
    6435                 :           0 :                     *m_cfg_changed_p = true;
    6436                 :           0 :                   release_defs (stmt);
    6437                 :           0 :                   continue;
    6438                 :             :                 }
    6439                 :             :               break;
    6440                 :             : 
    6441                 :         129 :             case CFN_COND_MUL:
    6442                 :         129 :               if (convert_mult_to_fma (stmt,
    6443                 :             :                                        gimple_call_arg (stmt, 1),
    6444                 :             :                                        gimple_call_arg (stmt, 2),
    6445                 :             :                                        &fma_state,
    6446                 :             :                                        gimple_call_arg (stmt, 0)))
    6447                 :             : 
    6448                 :             :                 {
    6449                 :          84 :                   gsi_remove (&gsi, true);
    6450                 :          84 :                   release_defs (stmt);
    6451                 :          84 :                   continue;
    6452                 :             :                 }
    6453                 :             :               break;
    6454                 :             : 
    6455                 :           0 :             case CFN_COND_LEN_MUL:
    6456                 :           0 :               if (convert_mult_to_fma (stmt,
    6457                 :             :                                        gimple_call_arg (stmt, 1),
    6458                 :             :                                        gimple_call_arg (stmt, 2),
    6459                 :             :                                        &fma_state,
    6460                 :             :                                        gimple_call_arg (stmt, 0),
    6461                 :             :                                        gimple_call_arg (stmt, 4),
    6462                 :             :                                        gimple_call_arg (stmt, 5)))
    6463                 :             : 
    6464                 :             :                 {
    6465                 :           0 :                   gsi_remove (&gsi, true);
    6466                 :           0 :                   release_defs (stmt);
    6467                 :           0 :                   continue;
    6468                 :             :                 }
    6469                 :             :               break;
    6470                 :             : 
    6471                 :     3479411 :             case CFN_LAST:
    6472                 :     3479411 :               cancel_fma_deferring (&fma_state);
    6473                 :     3479411 :               break;
    6474                 :             : 
    6475                 :             :             default:
    6476                 :             :               break;
    6477                 :             :             }
    6478                 :             :         }
    6479                 :    45821527 :       else if (gimple_code (stmt) == GIMPLE_COND)
    6480                 :             :         {
    6481                 :     3816653 :           match_single_bit_test (&gsi, stmt);
    6482                 :     3816653 :           optimize_spaceship (as_a <gcond *> (stmt));
    6483                 :             :         }
    6484                 :    70290970 :       gsi_next (&gsi);
    6485                 :             :     }
    6486                 :     9836340 :   if (fma_state.m_deferring_p
    6487                 :     7208665 :       && fma_state.m_initial_phi)
    6488                 :             :     {
    6489                 :         293 :       gcc_checking_assert (fma_state.m_last_result);
    6490                 :         293 :       if (!last_fma_candidate_feeds_initial_phi (&fma_state,
    6491                 :             :                                                  &m_last_result_set))
    6492                 :         168 :         cancel_fma_deferring (&fma_state);
    6493                 :             :       else
    6494                 :         125 :         m_last_result_set.add (fma_state.m_last_result);
    6495                 :             :     }
    6496                 :     9836340 : }
    6497                 :             : 
    6498                 :             : 
    6499                 :             : unsigned int
    6500                 :      927944 : pass_optimize_widening_mul::execute (function *fun)
    6501                 :             : {
    6502                 :      927944 :   bool cfg_changed = false;
    6503                 :             : 
    6504                 :      927944 :   memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
    6505                 :      927944 :   calculate_dominance_info (CDI_DOMINATORS);
    6506                 :      927944 :   renumber_gimple_stmt_uids (cfun);
    6507                 :             : 
    6508                 :      927944 :   math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    6509                 :             : 
    6510                 :      927944 :   statistics_counter_event (fun, "widening multiplications inserted",
    6511                 :             :                             widen_mul_stats.widen_mults_inserted);
    6512                 :      927944 :   statistics_counter_event (fun, "widening maccs inserted",
    6513                 :             :                             widen_mul_stats.maccs_inserted);
    6514                 :      927944 :   statistics_counter_event (fun, "fused multiply-adds inserted",
    6515                 :             :                             widen_mul_stats.fmas_inserted);
    6516                 :      927944 :   statistics_counter_event (fun, "divmod calls inserted",
    6517                 :             :                             widen_mul_stats.divmod_calls_inserted);
    6518                 :      927944 :   statistics_counter_event (fun, "highpart multiplications inserted",
    6519                 :             :                             widen_mul_stats.highpart_mults_inserted);
    6520                 :             : 
    6521                 :      927944 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    6522                 :             : }
    6523                 :             : 
    6524                 :             : } // anon namespace
    6525                 :             : 
    6526                 :             : gimple_opt_pass *
    6527                 :      282866 : make_pass_optimize_widening_mul (gcc::context *ctxt)
    6528                 :             : {
    6529                 :      282866 :   return new pass_optimize_widening_mul (ctxt);
    6530                 :             : }
        

Generated by: LCOV version 2.1-beta

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