LCOV - code coverage report
Current view: top level - gcc - tree-ssa-math-opts.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.5 % 3283 3005
Test Date: 2026-09-19 16:22:48 Functions: 99.0 % 101 100
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Global, SSA-based optimizations using mathematical identities.
       2              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it
       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 "stor-layout.h"
     106              : #include "tree-cfg.h"
     107              : #include "tree-dfa.h"
     108              : #include "tree-ssa.h"
     109              : #include "builtins.h"
     110              : #include "internal-fn.h"
     111              : #include "case-cfn-macros.h"
     112              : #include "optabs-libfuncs.h"
     113              : #include "tree-eh.h"
     114              : #include "targhooks.h"
     115              : #include "domwalk.h"
     116              : #include "tree-ssa-math-opts.h"
     117              : #include "dbgcnt.h"
     118              : #include "langhooks.h"
     119              : #include "cfghooks.h"
     120              : 
     121              : /* This structure represents one basic block that either computes a
     122              :    division, or is a common dominator for basic block that compute a
     123              :    division.  */
     124              : struct occurrence {
     125              :   /* The basic block represented by this structure.  */
     126              :   basic_block bb = basic_block();
     127              : 
     128              :   /* If non-NULL, the SSA_NAME holding the definition for a reciprocal
     129              :      inserted in BB.  */
     130              :   tree recip_def = tree();
     131              : 
     132              :   /* If non-NULL, the SSA_NAME holding the definition for a squared
     133              :      reciprocal inserted in BB.  */
     134              :   tree square_recip_def = tree();
     135              : 
     136              :   /* If non-NULL, the GIMPLE_ASSIGN for a reciprocal computation that
     137              :      was inserted in BB.  */
     138              :   gimple *recip_def_stmt = nullptr;
     139              : 
     140              :   /* Pointer to a list of "struct occurrence"s for blocks dominated
     141              :      by BB.  */
     142              :   struct occurrence *children = nullptr;
     143              : 
     144              :   /* Pointer to the next "struct occurrence"s in the list of blocks
     145              :      sharing a common dominator.  */
     146              :   struct occurrence *next = nullptr;
     147              : 
     148              :   /* The number of divisions that are in BB before compute_merit.  The
     149              :      number of divisions that are in BB or post-dominate it after
     150              :      compute_merit.  */
     151              :   int num_divisions = 0;
     152              : 
     153              :   /* True if the basic block has a division, false if it is a common
     154              :      dominator for basic blocks that do.  If it is false and trapping
     155              :      math is active, BB is not a candidate for inserting a reciprocal.  */
     156              :   bool bb_has_division = false;
     157              : 
     158              :   /* Construct a struct occurrence for basic block BB, and whose
     159              :      children list is headed by CHILDREN.  */
     160          618 :   occurrence (basic_block bb, struct occurrence *children)
     161          618 :   : bb (bb), children (children)
     162              :   {
     163          618 :     bb->aux = this;
     164              :   }
     165              : 
     166              :   /* Destroy a struct occurrence and remove it from its basic block.  */
     167          618 :   ~occurrence ()
     168              :   {
     169          618 :     bb->aux = nullptr;
     170          618 :   }
     171              : 
     172              :   /* Allocate memory for a struct occurrence from OCC_POOL.  */
     173              :   static void* operator new (size_t);
     174              : 
     175              :   /* Return memory for a struct occurrence to OCC_POOL.  */
     176              :   static void operator delete (void*, size_t);
     177              : };
     178              : 
     179              : static struct
     180              : {
     181              :   /* Number of 1.0/X ops inserted.  */
     182              :   int rdivs_inserted;
     183              : 
     184              :   /* Number of 1.0/FUNC ops inserted.  */
     185              :   int rfuncs_inserted;
     186              : } reciprocal_stats;
     187              : 
     188              : static struct
     189              : {
     190              :   /* Number of cexpi calls inserted.  */
     191              :   int inserted;
     192              : 
     193              :   /* Number of conversions removed.  */
     194              :   int conv_removed;
     195              : 
     196              : } sincos_stats;
     197              : 
     198              : static struct
     199              : {
     200              :   /* Number of widening multiplication ops inserted.  */
     201              :   int widen_mults_inserted;
     202              : 
     203              :   /* Number of integer multiply-and-accumulate ops inserted.  */
     204              :   int maccs_inserted;
     205              : 
     206              :   /* Number of fp fused multiply-add ops inserted.  */
     207              :   int fmas_inserted;
     208              : 
     209              :   /* Number of divmod calls inserted.  */
     210              :   int divmod_calls_inserted;
     211              : 
     212              :   /* Number of highpart multiplication ops inserted.  */
     213              :   int highpart_mults_inserted;
     214              : } widen_mul_stats;
     215              : 
     216              : /* The instance of "struct occurrence" representing the highest
     217              :    interesting block in the dominator tree.  */
     218              : static struct occurrence *occ_head;
     219              : 
     220              : /* Allocation pool for getting instances of "struct occurrence".  */
     221              : static object_allocator<occurrence> *occ_pool;
     222              : 
     223          618 : void* occurrence::operator new (size_t n)
     224              : {
     225          618 :   gcc_assert (n == sizeof(occurrence));
     226          618 :   return occ_pool->allocate_raw ();
     227              : }
     228              : 
     229          618 : void occurrence::operator delete (void *occ, size_t n)
     230              : {
     231          618 :   gcc_assert (n == sizeof(occurrence));
     232          618 :   occ_pool->remove_raw (occ);
     233          618 : }
     234              : 
     235              : /* Insert NEW_OCC into our subset of the dominator tree.  P_HEAD points to a
     236              :    list of "struct occurrence"s, one per basic block, having IDOM as
     237              :    their common dominator.
     238              : 
     239              :    We try to insert NEW_OCC as deep as possible in the tree, and we also
     240              :    insert any other block that is a common dominator for BB and one
     241              :    block already in the tree.  */
     242              : 
     243              : static void
     244          607 : insert_bb (struct occurrence *new_occ, basic_block idom,
     245              :            struct occurrence **p_head)
     246              : {
     247          612 :   struct occurrence *occ, **p_occ;
     248              : 
     249          635 :   for (p_occ = p_head; (occ = *p_occ) != NULL; )
     250              :     {
     251           28 :       basic_block bb = new_occ->bb, occ_bb = occ->bb;
     252           28 :       basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb);
     253           28 :       if (dom == bb)
     254              :         {
     255              :           /* BB dominates OCC_BB.  OCC becomes NEW_OCC's child: remove OCC
     256              :              from its list.  */
     257            6 :           *p_occ = occ->next;
     258            6 :           occ->next = new_occ->children;
     259            6 :           new_occ->children = occ;
     260              : 
     261              :           /* Try the next block (it may as well be dominated by BB).  */
     262              :         }
     263              : 
     264           22 :       else if (dom == occ_bb)
     265              :         {
     266              :           /* OCC_BB dominates BB.  Tail recurse to look deeper.  */
     267            5 :           insert_bb (new_occ, dom, &occ->children);
     268            5 :           return;
     269              :         }
     270              : 
     271           17 :       else if (dom != idom)
     272              :         {
     273           11 :           gcc_assert (!dom->aux);
     274              : 
     275              :           /* There is a dominator between IDOM and BB, add it and make
     276              :              two children out of NEW_OCC and OCC.  First, remove OCC from
     277              :              its list.  */
     278           11 :           *p_occ = occ->next;
     279           11 :           new_occ->next = occ;
     280           11 :           occ->next = NULL;
     281              : 
     282              :           /* None of the previous blocks has DOM as a dominator: if we tail
     283              :              recursed, we would reexamine them uselessly. Just switch BB with
     284              :              DOM, and go on looking for blocks dominated by DOM.  */
     285           11 :           new_occ = new occurrence (dom, new_occ);
     286              :         }
     287              : 
     288              :       else
     289              :         {
     290              :           /* Nothing special, go on with the next element.  */
     291            6 :           p_occ = &occ->next;
     292              :         }
     293              :     }
     294              : 
     295              :   /* No place was found as a child of IDOM.  Make BB a sibling of IDOM.  */
     296          607 :   new_occ->next = *p_head;
     297          607 :   *p_head = new_occ;
     298              : }
     299              : 
     300              : /* Register that we found a division in BB.
     301              :    IMPORTANCE is a measure of how much weighting to give
     302              :    that division.  Use IMPORTANCE = 2 to register a single
     303              :    division.  If the division is going to be found multiple
     304              :    times use 1 (as it is with squares).  */
     305              : 
     306              : static inline void
     307          709 : register_division_in (basic_block bb, int importance)
     308              : {
     309          709 :   struct occurrence *occ;
     310              : 
     311          709 :   occ = (struct occurrence *) bb->aux;
     312          709 :   if (!occ)
     313              :     {
     314          607 :       occ = new occurrence (bb, NULL);
     315          607 :       insert_bb (occ, ENTRY_BLOCK_PTR_FOR_FN (cfun), &occ_head);
     316              :     }
     317              : 
     318          709 :   occ->bb_has_division = true;
     319          709 :   occ->num_divisions += importance;
     320          709 : }
     321              : 
     322              : 
     323              : /* Compute the number of divisions that postdominate each block in OCC and
     324              :    its children.  */
     325              : 
     326              : static void
     327           26 : compute_merit (struct occurrence *occ)
     328              : {
     329           26 :   struct occurrence *occ_child;
     330           26 :   basic_block dom = occ->bb;
     331              : 
     332           45 :   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
     333              :     {
     334           19 :       basic_block bb;
     335           19 :       if (occ_child->children)
     336            3 :         compute_merit (occ_child);
     337              : 
     338           19 :       if (flag_exceptions)
     339            6 :         bb = single_noncomplex_succ (dom);
     340              :       else
     341              :         bb = dom;
     342              : 
     343           19 :       if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb))
     344           12 :         occ->num_divisions += occ_child->num_divisions;
     345              :     }
     346           26 : }
     347              : 
     348              : 
     349              : /* Return whether USE_STMT is a floating-point division by DEF.  */
     350              : static inline bool
     351       352854 : is_division_by (gimple *use_stmt, tree def)
     352              : {
     353       352854 :   return is_gimple_assign (use_stmt)
     354       242976 :          && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
     355         1251 :          && gimple_assign_rhs2 (use_stmt) == def
     356              :          /* Do not recognize x / x as valid division, as we are getting
     357              :             confused later by replacing all immediate uses x in such
     358              :             a stmt.  */
     359          879 :          && gimple_assign_rhs1 (use_stmt) != def
     360       353733 :          && !stmt_can_throw_internal (cfun, use_stmt);
     361              : }
     362              : 
     363              : /* Return TRUE if USE_STMT is a multiplication of DEF by A.  */
     364              : static inline bool
     365       349063 : is_mult_by (gimple *use_stmt, tree def, tree a)
     366              : {
     367       349063 :   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
     368       349063 :       && gimple_assign_rhs_code (use_stmt) == MULT_EXPR)
     369              :     {
     370        80029 :       tree op0 = gimple_assign_rhs1 (use_stmt);
     371        80029 :       tree op1 = gimple_assign_rhs2 (use_stmt);
     372              : 
     373        80029 :       return (op0 == def && op1 == a)
     374        80029 :               || (op0 == a && op1 == def);
     375              :     }
     376              :   return 0;
     377              : }
     378              : 
     379              : /* Return whether USE_STMT is DEF * DEF.  */
     380              : static inline bool
     381       349018 : is_square_of (gimple *use_stmt, tree def)
     382              : {
     383            5 :   return is_mult_by (use_stmt, def, def);
     384              : }
     385              : 
     386              : /* Return whether USE_STMT is a floating-point division by
     387              :    DEF * DEF.  */
     388              : static inline bool
     389          192 : is_division_by_square (gimple *use_stmt, tree def)
     390              : {
     391          192 :   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
     392          185 :       && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
     393            7 :       && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
     394          199 :       && !stmt_can_throw_internal (cfun, use_stmt))
     395              :     {
     396            7 :       tree denominator = gimple_assign_rhs2 (use_stmt);
     397            7 :       if (TREE_CODE (denominator) == SSA_NAME)
     398            7 :         return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
     399              :     }
     400              :   return 0;
     401              : }
     402              : 
     403              : /* Walk the subset of the dominator tree rooted at OCC, setting the
     404              :    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
     405              :    the given basic block.  The field may be left NULL, of course,
     406              :    if it is not possible or profitable to do the optimization.
     407              : 
     408              :    DEF_BSI is an iterator pointing at the statement defining DEF.
     409              :    If RECIP_DEF is set, a dominator already has a computation that can
     410              :    be used.
     411              : 
     412              :    If should_insert_square_recip is set, then this also inserts
     413              :    the square of the reciprocal immediately after the definition
     414              :    of the reciprocal.  */
     415              : 
     416              : static void
     417           42 : insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
     418              :                     tree def, tree recip_def, tree square_recip_def,
     419              :                     int should_insert_square_recip, int threshold)
     420              : {
     421           42 :   tree type;
     422           42 :   gassign *new_stmt, *new_square_stmt;
     423           42 :   gimple_stmt_iterator gsi;
     424           42 :   struct occurrence *occ_child;
     425              : 
     426           42 :   if (!recip_def
     427           26 :       && (occ->bb_has_division || !flag_trapping_math)
     428              :       /* Divide by two as all divisions are counted twice in
     429              :          the costing loop.  */
     430           25 :       && occ->num_divisions / 2 >= threshold)
     431              :     {
     432              :       /* Make a variable with the replacement and substitute it.  */
     433           24 :       type = TREE_TYPE (def);
     434           24 :       recip_def = create_tmp_reg (type, "reciptmp");
     435           24 :       new_stmt = gimple_build_assign (recip_def, RDIV_EXPR,
     436              :                                       build_one_cst (type), def);
     437              : 
     438           24 :       if (should_insert_square_recip)
     439              :         {
     440            4 :           square_recip_def = create_tmp_reg (type, "powmult_reciptmp");
     441            4 :           new_square_stmt = gimple_build_assign (square_recip_def, MULT_EXPR,
     442              :                                                  recip_def, recip_def);
     443              :         }
     444              : 
     445           24 :       if (occ->bb_has_division)
     446              :         {
     447              :           /* Case 1: insert before an existing division.  */
     448           21 :           gsi = gsi_after_labels (occ->bb);
     449          212 :           while (!gsi_end_p (gsi)
     450          212 :                  && (!is_division_by (gsi_stmt (gsi), def))
     451          404 :                  && (!is_division_by_square (gsi_stmt (gsi), def)))
     452          191 :             gsi_next (&gsi);
     453              : 
     454           21 :           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
     455           21 :           if (should_insert_square_recip)
     456            3 :             gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
     457              :         }
     458            3 :       else if (def_gsi && occ->bb == gsi_bb (*def_gsi))
     459              :         {
     460              :           /* Case 2: insert right after the definition.  Note that this will
     461              :              never happen if the definition statement can throw, because in
     462              :              that case the sole successor of the statement's basic block will
     463              :              dominate all the uses as well.  */
     464            2 :           gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
     465            2 :           if (should_insert_square_recip)
     466            1 :             gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT);
     467              :         }
     468              :       else
     469              :         {
     470              :           /* Case 3: insert in a basic block not containing defs/uses.  */
     471            1 :           gsi = gsi_after_labels (occ->bb);
     472            1 :           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
     473            1 :           if (should_insert_square_recip)
     474            0 :             gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
     475              :         }
     476              : 
     477           24 :       reciprocal_stats.rdivs_inserted++;
     478              : 
     479           24 :       occ->recip_def_stmt = new_stmt;
     480              :     }
     481              : 
     482           42 :   occ->recip_def = recip_def;
     483           42 :   occ->square_recip_def = square_recip_def;
     484           61 :   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
     485           19 :     insert_reciprocals (def_gsi, occ_child, def, recip_def,
     486              :                         square_recip_def, should_insert_square_recip,
     487              :                         threshold);
     488           42 : }
     489              : 
     490              : /* Replace occurrences of expr / (x * x) with expr * ((1 / x) * (1 / x)).
     491              :    Take as argument the use for (x * x).  */
     492              : static inline void
     493            4 : replace_reciprocal_squares (use_operand_p use_p)
     494              : {
     495            4 :   gimple *use_stmt = USE_STMT (use_p);
     496            4 :   basic_block bb = gimple_bb (use_stmt);
     497            4 :   struct occurrence *occ = (struct occurrence *) bb->aux;
     498              : 
     499            8 :   if (optimize_bb_for_speed_p (bb) && occ->square_recip_def
     500            8 :       && occ->recip_def)
     501              :     {
     502            4 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
     503            4 :       gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
     504            4 :       gimple_assign_set_rhs2 (use_stmt, occ->square_recip_def);
     505            4 :       SET_USE (use_p, occ->square_recip_def);
     506            4 :       fold_stmt_inplace (&gsi);
     507            4 :       update_stmt (use_stmt);
     508              :     }
     509            4 : }
     510              : 
     511              : 
     512              : /* Replace the division at USE_P with a multiplication by the reciprocal, if
     513              :    possible.  */
     514              : 
     515              : static inline void
     516          105 : replace_reciprocal (use_operand_p use_p)
     517              : {
     518          105 :   gimple *use_stmt = USE_STMT (use_p);
     519          105 :   basic_block bb = gimple_bb (use_stmt);
     520          105 :   struct occurrence *occ = (struct occurrence *) bb->aux;
     521              : 
     522          105 :   if (optimize_bb_for_speed_p (bb)
     523          105 :       && occ->recip_def && use_stmt != occ->recip_def_stmt)
     524              :     {
     525           80 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
     526           80 :       gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
     527           80 :       SET_USE (use_p, occ->recip_def);
     528           80 :       fold_stmt_inplace (&gsi);
     529           80 :       update_stmt (use_stmt);
     530              :     }
     531          105 : }
     532              : 
     533              : 
     534              : /* Free OCC and return one more "struct occurrence" to be freed.  */
     535              : 
     536              : static struct occurrence *
     537          618 : free_bb (struct occurrence *occ)
     538              : {
     539          618 :   struct occurrence *child, *next;
     540              : 
     541              :   /* First get the two pointers hanging off OCC.  */
     542          618 :   next = occ->next;
     543          618 :   child = occ->children;
     544          618 :   delete occ;
     545              : 
     546              :   /* Now ensure that we don't recurse unless it is necessary.  */
     547          618 :   if (!child)
     548              :     return next;
     549              :   else
     550              :     {
     551           19 :       while (next)
     552            0 :         next = free_bb (next);
     553              : 
     554              :       return child;
     555              :     }
     556              : }
     557              : 
     558              : /* Transform sequences like
     559              :    t = sqrt (a)
     560              :    x = 1.0 / t;
     561              :    r1 = x * x;
     562              :    r2 = a * x;
     563              :    into:
     564              :    t = sqrt (a)
     565              :    r1 = 1.0 / a;
     566              :    r2 = t;
     567              :    x = r1 * r2;
     568              :    depending on the uses of x, r1, r2.  This removes one multiplication and
     569              :    allows the sqrt and division operations to execute in parallel.
     570              :    DEF_GSI is the gsi of the initial division by sqrt that defines
     571              :    DEF (x in the example above).  */
     572              : 
     573              : static void
     574          556 : optimize_recip_sqrt (gimple_stmt_iterator *def_gsi, tree def)
     575              : {
     576          556 :   gimple *use_stmt;
     577          556 :   imm_use_iterator use_iter;
     578          556 :   gimple *stmt = gsi_stmt (*def_gsi);
     579          556 :   tree x = def;
     580          556 :   tree orig_sqrt_ssa_name = gimple_assign_rhs2 (stmt);
     581          556 :   tree div_rhs1 = gimple_assign_rhs1 (stmt);
     582              : 
     583          556 :   if (TREE_CODE (orig_sqrt_ssa_name) != SSA_NAME
     584          551 :       || TREE_CODE (div_rhs1) != REAL_CST
     585          742 :       || !real_equal (&TREE_REAL_CST (div_rhs1), &dconst1))
     586          544 :     return;
     587              : 
     588          110 :   gcall *sqrt_stmt
     589          586 :     = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (orig_sqrt_ssa_name));
     590              : 
     591           42 :   if (!sqrt_stmt || !gimple_call_lhs (sqrt_stmt))
     592              :     return;
     593              : 
     594           42 :   switch (gimple_call_combined_fn (sqrt_stmt))
     595              :     {
     596           31 :     CASE_CFN_SQRT:
     597           31 :     CASE_CFN_SQRT_FN:
     598           31 :       break;
     599              : 
     600              :     default:
     601              :       return;
     602              :     }
     603           31 :   tree a = gimple_call_arg (sqrt_stmt, 0);
     604              : 
     605              :   /* We have 'a' and 'x'.  Now analyze the uses of 'x'.  */
     606              : 
     607              :   /* Statements that use x in x * x.  */
     608           43 :   auto_vec<gimple *> sqr_stmts;
     609              :   /* Statements that use x in a * x.  */
     610           12 :   auto_vec<gimple *> mult_stmts;
     611           31 :   bool has_other_use = false;
     612           31 :   bool mult_on_main_path = false;
     613              : 
     614           89 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, x)
     615              :     {
     616           58 :       if (is_gimple_debug (use_stmt))
     617            1 :         continue;
     618           57 :       if (is_square_of (use_stmt, x))
     619              :         {
     620           12 :           sqr_stmts.safe_push (use_stmt);
     621           12 :           if (gimple_bb (use_stmt) == gimple_bb (stmt))
     622           58 :             mult_on_main_path = true;
     623              :         }
     624           45 :       else if (is_mult_by (use_stmt, x, a))
     625              :         {
     626           14 :           mult_stmts.safe_push (use_stmt);
     627           14 :           if (gimple_bb (use_stmt) == gimple_bb (stmt))
     628           58 :             mult_on_main_path = true;
     629              :         }
     630              :       else
     631              :         has_other_use = true;
     632           31 :     }
     633              : 
     634              :   /* In the x * x and a * x cases we just rewire stmt operands or
     635              :      remove multiplications.  In the has_other_use case we introduce
     636              :      a multiplication so make sure we don't introduce a multiplication
     637              :      on a path where there was none.  */
     638           31 :   if (has_other_use && !mult_on_main_path)
     639           19 :     return;
     640              : 
     641           12 :   if (sqr_stmts.is_empty () && mult_stmts.is_empty ())
     642              :     return;
     643              : 
     644              :   /* If x = 1.0 / sqrt (a) has uses other than those optimized here we want
     645              :      to be able to compose it from the sqr and mult cases.  */
     646           41 :   if (has_other_use && (sqr_stmts.is_empty () || mult_stmts.is_empty ()))
     647              :     return;
     648              : 
     649           12 :   if (dump_file)
     650              :     {
     651           10 :       fprintf (dump_file, "Optimizing reciprocal sqrt multiplications of\n");
     652           10 :       print_gimple_stmt (dump_file, sqrt_stmt, 0, TDF_NONE);
     653           10 :       print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     654           10 :       fprintf (dump_file, "\n");
     655              :     }
     656              : 
     657           12 :   bool delete_div = !has_other_use;
     658           12 :   tree sqr_ssa_name = NULL_TREE;
     659           22 :   if (!sqr_stmts.is_empty ())
     660              :     {
     661              :       /* r1 = x * x.  Transform the original
     662              :          x = 1.0 / t
     663              :          into
     664              :          tmp1 = 1.0 / a
     665              :          r1 = tmp1.  */
     666              : 
     667           10 :       sqr_ssa_name
     668           10 :         = make_temp_ssa_name (TREE_TYPE (a), NULL, "recip_sqrt_sqr");
     669              : 
     670           10 :       if (dump_file)
     671              :         {
     672           10 :           fprintf (dump_file, "Replacing original division\n");
     673           10 :           print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     674           10 :           fprintf (dump_file, "with new division\n");
     675              :         }
     676           10 :       stmt
     677           10 :         = gimple_build_assign (sqr_ssa_name, gimple_assign_rhs_code (stmt),
     678              :                                gimple_assign_rhs1 (stmt), a);
     679           10 :       gsi_insert_before (def_gsi, stmt, GSI_SAME_STMT);
     680           10 :       gsi_remove (def_gsi, true);
     681           10 :       *def_gsi = gsi_for_stmt (stmt);
     682           10 :       fold_stmt_inplace (def_gsi);
     683           10 :       update_stmt (stmt);
     684              : 
     685           10 :       if (dump_file)
     686           10 :         print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
     687              : 
     688           10 :       delete_div = false;
     689           10 :       gimple *sqr_stmt;
     690           10 :       unsigned int i;
     691           20 :       FOR_EACH_VEC_ELT (sqr_stmts, i, sqr_stmt)
     692              :         {
     693           10 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (sqr_stmt);
     694           10 :           gimple_assign_set_rhs_from_tree (&gsi2, sqr_ssa_name);
     695           10 :           update_stmt (sqr_stmt);
     696              :         }
     697              :     }
     698           24 :   if (!mult_stmts.is_empty ())
     699              :     {
     700              :       /* r2 = a * x.  Transform this into:
     701              :          r2 = t (The original sqrt (a)).  */
     702              :       unsigned int i;
     703           24 :       gimple *mult_stmt = NULL;
     704           24 :       FOR_EACH_VEC_ELT (mult_stmts, i, mult_stmt)
     705              :         {
     706           12 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (mult_stmt);
     707              : 
     708           12 :           if (dump_file)
     709              :             {
     710           10 :               fprintf (dump_file, "Replacing squaring multiplication\n");
     711           10 :               print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
     712           10 :               fprintf (dump_file, "with assignment\n");
     713              :             }
     714           12 :           gimple_assign_set_rhs_from_tree (&gsi2, orig_sqrt_ssa_name);
     715           12 :           fold_stmt_inplace (&gsi2);
     716           12 :           update_stmt (mult_stmt);
     717           12 :           if (dump_file)
     718           10 :             print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
     719              :       }
     720              :     }
     721              : 
     722           12 :   if (has_other_use)
     723              :     {
     724              :       /* Using the two temporaries tmp1, tmp2 from above
     725              :          the original x is now:
     726              :          x = tmp1 * tmp2.  */
     727           10 :       gcc_assert (orig_sqrt_ssa_name);
     728           10 :       gcc_assert (sqr_ssa_name);
     729              : 
     730           10 :       gimple *new_stmt
     731           10 :         = gimple_build_assign (x, MULT_EXPR,
     732              :                                orig_sqrt_ssa_name, sqr_ssa_name);
     733           10 :       gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
     734           10 :       update_stmt (stmt);
     735              :     }
     736            2 :   else if (delete_div)
     737              :     {
     738              :       /* Remove the original division.  */
     739            2 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
     740            2 :       gsi_remove (&gsi2, true);
     741            2 :       release_defs (stmt);
     742              :     }
     743              :   else
     744            0 :     release_ssa_name (x);
     745              : }
     746              : 
     747              : /* Look for floating-point divisions among DEF's uses, and try to
     748              :    replace them by multiplications with the reciprocal.  Add
     749              :    as many statements computing the reciprocal as needed.
     750              : 
     751              :    DEF must be a GIMPLE register of a floating-point type.  */
     752              : 
     753              : static void
     754       213262 : execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
     755              : {
     756       213262 :   use_operand_p use_p, square_use_p;
     757       213262 :   imm_use_iterator use_iter, square_use_iter;
     758       213262 :   tree square_def;
     759       213262 :   struct occurrence *occ;
     760       213262 :   int count = 0;
     761       213262 :   int threshold;
     762       213262 :   int square_recip_count = 0;
     763       213262 :   int sqrt_recip_count = 0;
     764              : 
     765       213262 :   gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && TREE_CODE (def) == SSA_NAME);
     766       213262 :   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
     767              : 
     768              :   /* If DEF is a square (x * x), count the number of divisions by x.
     769              :      If there are more divisions by x than by (DEF * DEF), prefer to optimize
     770              :      the reciprocal of x instead of DEF.  This improves cases like:
     771              :        def = x * x
     772              :        t0 = a / def
     773              :        t1 = b / def
     774              :        t2 = c / x
     775              :      Reciprocal optimization of x results in 1 division rather than 2 or 3.  */
     776       213262 :   gimple *def_stmt = SSA_NAME_DEF_STMT (def);
     777              : 
     778       213262 :   if (is_gimple_assign (def_stmt)
     779       166784 :       && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
     780        40571 :       && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
     781       253756 :       && gimple_assign_rhs1 (def_stmt) == gimple_assign_rhs2 (def_stmt))
     782              :     {
     783          671 :       tree op0 = gimple_assign_rhs1 (def_stmt);
     784              : 
     785         2754 :       FOR_EACH_IMM_USE_FAST (use_p, use_iter, op0)
     786              :         {
     787         2083 :           gimple *use_stmt = USE_STMT (use_p);
     788         2083 :           if (is_division_by (use_stmt, op0))
     789           17 :             sqrt_recip_count++;
     790          671 :         }
     791              :     }
     792              : 
     793       562211 :   FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
     794              :     {
     795       348949 :       gimple *use_stmt = USE_STMT (use_p);
     796       348949 :       if (is_division_by (use_stmt, def))
     797              :         {
     798          637 :           register_division_in (gimple_bb (use_stmt), 2);
     799          637 :           count++;
     800              :         }
     801              : 
     802       348949 :       if (is_square_of (use_stmt, def))
     803              :         {
     804         1350 :           square_def = gimple_assign_lhs (use_stmt);
     805         2832 :           FOR_EACH_IMM_USE_FAST (square_use_p, square_use_iter, square_def)
     806              :             {
     807         1482 :               gimple *square_use_stmt = USE_STMT (square_use_p);
     808         1482 :               if (is_division_by (square_use_stmt, square_def))
     809              :                 {
     810              :                   /* This is executed twice for each division by a square.  */
     811           72 :                   register_division_in (gimple_bb (square_use_stmt), 1);
     812           72 :                   square_recip_count++;
     813              :                 }
     814         1350 :             }
     815              :         }
     816       213262 :     }
     817              : 
     818              :   /* Square reciprocals were counted twice above.  */
     819       213262 :   square_recip_count /= 2;
     820              : 
     821              :   /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x).  */
     822       213262 :   if (sqrt_recip_count > square_recip_count)
     823           17 :     goto out;
     824              : 
     825              :   /* Do the expensive part only if we can hope to optimize something.  */
     826       213245 :   if (count + square_recip_count >= threshold && count >= 1)
     827              :     {
     828           23 :       gimple *use_stmt;
     829           46 :       for (occ = occ_head; occ; occ = occ->next)
     830              :         {
     831           23 :           compute_merit (occ);
     832           23 :           insert_reciprocals (def_gsi, occ, def, NULL, NULL,
     833              :                               square_recip_count, threshold);
     834              :         }
     835              : 
     836          143 :       FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
     837              :         {
     838          120 :           if (is_division_by (use_stmt, def))
     839              :             {
     840          210 :               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
     841          105 :                 replace_reciprocal (use_p);
     842              :             }
     843           20 :           else if (square_recip_count > 0 && is_square_of (use_stmt, def))
     844              :             {
     845           12 :               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
     846              :                 {
     847              :                   /* Find all uses of the square that are divisions and
     848              :                    * replace them by multiplications with the inverse.  */
     849            8 :                   imm_use_iterator square_iterator;
     850            8 :                   gimple *powmult_use_stmt = USE_STMT (use_p);
     851            8 :                   tree powmult_def_name = gimple_assign_lhs (powmult_use_stmt);
     852              : 
     853           16 :                   FOR_EACH_IMM_USE_STMT (powmult_use_stmt,
     854              :                                          square_iterator, powmult_def_name)
     855           16 :                     FOR_EACH_IMM_USE_ON_STMT (square_use_p, square_iterator)
     856              :                       {
     857            8 :                         gimple *powmult_use_stmt = USE_STMT (square_use_p);
     858            8 :                         if (is_division_by (powmult_use_stmt, powmult_def_name))
     859            4 :                           replace_reciprocal_squares (square_use_p);
     860            8 :                       }
     861              :                 }
     862              :             }
     863           23 :         }
     864              :     }
     865              : 
     866       213222 : out:
     867       213880 :   for (occ = occ_head; occ; )
     868          618 :     occ = free_bb (occ);
     869              : 
     870       213262 :   occ_head = NULL;
     871       213262 : }
     872              : 
     873              : /* Return an internal function that implements the reciprocal of CALL,
     874              :    or IFN_LAST if there is no such function that the target supports.  */
     875              : 
     876              : internal_fn
     877          113 : internal_fn_reciprocal (gcall *call)
     878              : {
     879          113 :   internal_fn ifn;
     880              : 
     881          113 :   switch (gimple_call_combined_fn (call))
     882              :     {
     883           97 :     CASE_CFN_SQRT:
     884           97 :     CASE_CFN_SQRT_FN:
     885           97 :       ifn = IFN_RSQRT;
     886           97 :       break;
     887              : 
     888              :     default:
     889              :       return IFN_LAST;
     890              :     }
     891              : 
     892           97 :   tree_pair types = direct_internal_fn_types (ifn, call);
     893           97 :   if (!direct_internal_fn_supported_p (ifn, types, OPTIMIZE_FOR_SPEED))
     894           44 :     return IFN_LAST;
     895              : 
     896              :   return ifn;
     897              : }
     898              : 
     899              : /* Go through all the floating-point SSA_NAMEs, and call
     900              :    execute_cse_reciprocals_1 on each of them.  */
     901              : namespace {
     902              : 
     903              : const pass_data pass_data_cse_reciprocals =
     904              : {
     905              :   GIMPLE_PASS, /* type */
     906              :   "recip", /* name */
     907              :   OPTGROUP_NONE, /* optinfo_flags */
     908              :   TV_TREE_RECIP, /* tv_id */
     909              :   PROP_ssa, /* properties_required */
     910              :   0, /* properties_provided */
     911              :   0, /* properties_destroyed */
     912              :   0, /* todo_flags_start */
     913              :   TODO_update_ssa, /* todo_flags_finish */
     914              : };
     915              : 
     916              : class pass_cse_reciprocals : public gimple_opt_pass
     917              : {
     918              : public:
     919       294587 :   pass_cse_reciprocals (gcc::context *ctxt)
     920       589174 :     : gimple_opt_pass (pass_data_cse_reciprocals, ctxt)
     921              :   {}
     922              : 
     923              :   /* opt_pass methods: */
     924      1062413 :   bool gate (function *) final override
     925              :   {
     926      1062413 :     return optimize && flag_reciprocal_math;
     927              :   }
     928              :   unsigned int execute (function *) final override;
     929              : 
     930              : }; // class pass_cse_reciprocals
     931              : 
     932              : unsigned int
     933         8801 : pass_cse_reciprocals::execute (function *fun)
     934              : {
     935         8801 :   basic_block bb;
     936         8801 :   tree arg;
     937              : 
     938         8801 :   occ_pool = new object_allocator<occurrence> ("dominators for recip");
     939              : 
     940         8801 :   memset (&reciprocal_stats, 0, sizeof (reciprocal_stats));
     941         8801 :   calculate_dominance_info (CDI_DOMINATORS);
     942         8801 :   calculate_dominance_info (CDI_POST_DOMINATORS);
     943              : 
     944         8801 :   if (flag_checking)
     945        94425 :     FOR_EACH_BB_FN (bb, fun)
     946        85624 :       gcc_assert (!bb->aux);
     947              : 
     948        21826 :   for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg))
     949        20685 :     if (FLOAT_TYPE_P (TREE_TYPE (arg))
     950        14112 :         && is_gimple_reg (arg))
     951              :       {
     952         6451 :         tree name = ssa_default_def (fun, arg);
     953         6451 :         if (name)
     954         5456 :           execute_cse_reciprocals_1 (NULL, name);
     955              :       }
     956              : 
     957        94425 :   FOR_EACH_BB_FN (bb, fun)
     958              :     {
     959        85624 :       tree def;
     960              : 
     961       196952 :       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     962       111328 :            gsi_next (&gsi))
     963              :         {
     964       111328 :           gphi *phi = gsi.phi ();
     965       111328 :           def = PHI_RESULT (phi);
     966       111328 :           if (! virtual_operand_p (def)
     967       111328 :               && FLOAT_TYPE_P (TREE_TYPE (def)))
     968        30805 :             execute_cse_reciprocals_1 (NULL, def);
     969              :         }
     970              : 
     971      1374809 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
     972      1289185 :            gsi_next (&gsi))
     973              :         {
     974      1289185 :           gimple *stmt = gsi_stmt (gsi);
     975              : 
     976      2578370 :           if (gimple_has_lhs (stmt)
     977       809617 :               && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
     978       769382 :               && FLOAT_TYPE_P (TREE_TYPE (def))
     979       199920 :               && TREE_CODE (def) == SSA_NAME)
     980              :             {
     981       177001 :               execute_cse_reciprocals_1 (&gsi, def);
     982       177001 :               stmt = gsi_stmt (gsi);
     983       177001 :               if (flag_unsafe_math_optimizations
     984       176956 :                   && is_gimple_assign (stmt)
     985       166741 :                   && gimple_assign_lhs (stmt) == def
     986       166739 :                   && !stmt_can_throw_internal (cfun, stmt)
     987       343696 :                   && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
     988          556 :                 optimize_recip_sqrt (&gsi, def);
     989              :             }
     990              :         }
     991              : 
     992        85624 :       if (optimize_bb_for_size_p (bb))
     993         5361 :         continue;
     994              : 
     995              :       /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b).  */
     996      1347565 :       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
     997      1267302 :            gsi_next (&gsi))
     998              :         {
     999      1267302 :           gimple *stmt = gsi_stmt (gsi);
    1000              : 
    1001      1267302 :           if (is_gimple_assign (stmt)
    1002      1267302 :               && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
    1003              :             {
    1004          598 :               tree arg1 = gimple_assign_rhs2 (stmt);
    1005          598 :               gimple *stmt1;
    1006              : 
    1007          598 :               if (TREE_CODE (arg1) != SSA_NAME)
    1008            5 :                 continue;
    1009              : 
    1010          593 :               stmt1 = SSA_NAME_DEF_STMT (arg1);
    1011              : 
    1012          593 :               if (is_gimple_call (stmt1)
    1013          593 :                   && gimple_call_lhs (stmt1))
    1014              :                 {
    1015          113 :                   bool fail;
    1016          113 :                   imm_use_iterator ui;
    1017          113 :                   use_operand_p use_p;
    1018          113 :                   tree fndecl = NULL_TREE;
    1019              : 
    1020          113 :                   gcall *call = as_a <gcall *> (stmt1);
    1021          113 :                   internal_fn ifn = internal_fn_reciprocal (call);
    1022          113 :                   if (ifn == IFN_LAST)
    1023              :                     {
    1024           60 :                       fndecl = gimple_call_fndecl (call);
    1025          120 :                       if (!fndecl
    1026           60 :                           || !fndecl_built_in_p (fndecl, BUILT_IN_MD))
    1027           62 :                         continue;
    1028            0 :                       fndecl = targetm.builtin_reciprocal (fndecl);
    1029            0 :                       if (!fndecl)
    1030            0 :                         continue;
    1031              :                     }
    1032              : 
    1033              :                   /* Check that all uses of the SSA name are divisions,
    1034              :                      otherwise replacing the defining statement will do
    1035              :                      the wrong thing.  */
    1036           53 :                   fail = false;
    1037          106 :                   FOR_EACH_IMM_USE_FAST (use_p, ui, arg1)
    1038              :                     {
    1039           55 :                       gimple *stmt2 = USE_STMT (use_p);
    1040           55 :                       if (is_gimple_debug (stmt2))
    1041            0 :                         continue;
    1042           55 :                       if (!is_gimple_assign (stmt2)
    1043           55 :                           || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
    1044           53 :                           || gimple_assign_rhs1 (stmt2) == arg1
    1045          108 :                           || gimple_assign_rhs2 (stmt2) != arg1)
    1046              :                         {
    1047              :                           fail = true;
    1048              :                           break;
    1049              :                         }
    1050           53 :                     }
    1051           53 :                   if (fail)
    1052            2 :                     continue;
    1053              : 
    1054           51 :                   gimple_replace_ssa_lhs (call, arg1);
    1055           51 :                   reset_flow_sensitive_info (arg1);
    1056           51 :                   if (gimple_call_internal_p (call) != (ifn != IFN_LAST))
    1057              :                     {
    1058           30 :                       auto_vec<tree, 4> args;
    1059           30 :                       for (unsigned int i = 0;
    1060           60 :                            i < gimple_call_num_args (call); i++)
    1061           30 :                         args.safe_push (gimple_call_arg (call, i));
    1062           30 :                       gcall *stmt2;
    1063           30 :                       if (ifn == IFN_LAST)
    1064            0 :                         stmt2 = gimple_build_call_vec (fndecl, args);
    1065              :                       else
    1066           30 :                         stmt2 = gimple_build_call_internal_vec (ifn, args);
    1067           30 :                       gimple_call_set_lhs (stmt2, arg1);
    1068           30 :                       gimple_move_vops (stmt2, call);
    1069           30 :                       gimple_call_set_nothrow (stmt2,
    1070              :                                                gimple_call_nothrow_p (call));
    1071           30 :                       gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    1072           30 :                       gsi_replace (&gsi2, stmt2, true);
    1073           30 :                     }
    1074              :                   else
    1075              :                     {
    1076           21 :                       if (ifn == IFN_LAST)
    1077            0 :                         gimple_call_set_fndecl (call, fndecl);
    1078              :                       else
    1079           21 :                         gimple_call_set_internal_fn (call, ifn);
    1080           21 :                       update_stmt (call);
    1081              :                     }
    1082           51 :                   reciprocal_stats.rfuncs_inserted++;
    1083              : 
    1084          102 :                   FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
    1085              :                     {
    1086           51 :                       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    1087           51 :                       gimple_assign_set_rhs_code (stmt, MULT_EXPR);
    1088           51 :                       fold_stmt_inplace (&gsi);
    1089           51 :                       update_stmt (stmt);
    1090           51 :                     }
    1091              :                 }
    1092              :             }
    1093              :         }
    1094              :     }
    1095              : 
    1096         8801 :   statistics_counter_event (fun, "reciprocal divs inserted",
    1097              :                             reciprocal_stats.rdivs_inserted);
    1098         8801 :   statistics_counter_event (fun, "reciprocal functions inserted",
    1099              :                             reciprocal_stats.rfuncs_inserted);
    1100              : 
    1101         8801 :   free_dominance_info (CDI_DOMINATORS);
    1102         8801 :   free_dominance_info (CDI_POST_DOMINATORS);
    1103        17602 :   delete occ_pool;
    1104         8801 :   return 0;
    1105              : }
    1106              : 
    1107              : } // anon namespace
    1108              : 
    1109              : gimple_opt_pass *
    1110       294587 : make_pass_cse_reciprocals (gcc::context *ctxt)
    1111              : {
    1112       294587 :   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         1069 : execute_cse_conv_1 (tree name, bool *cfg_changed)
    1122              : {
    1123         1069 :   if (SSA_NAME_IS_DEFAULT_DEF (name)
    1124         1069 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
    1125              :     return name;
    1126              : 
    1127          969 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
    1128              : 
    1129          969 :   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          378 :         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         1290 : maybe_record_sincos (vec<gimple *> *stmts,
    1223              :                      basic_block *top_bb, gimple *use_stmt)
    1224              : {
    1225         1290 :   basic_block use_bb = gimple_bb (use_stmt);
    1226         1290 :   if (*top_bb
    1227         1290 :       && (*top_bb == use_bb
    1228           66 :           || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
    1229          168 :     stmts->safe_push (use_stmt);
    1230         1122 :   else if (!*top_bb
    1231         1122 :            || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
    1232              :     {
    1233         1102 :       stmts->safe_push (use_stmt);
    1234         1102 :       *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         1069 : execute_cse_sincos_1 (tree name)
    1252              : {
    1253         1069 :   gimple_stmt_iterator gsi;
    1254         1069 :   imm_use_iterator use_iter;
    1255         1069 :   tree fndecl, res, type = NULL_TREE;
    1256         1069 :   gimple *def_stmt, *use_stmt, *stmt;
    1257         1069 :   int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
    1258         1069 :   auto_vec<gimple *> stmts;
    1259         1069 :   basic_block top_bb = NULL;
    1260         1069 :   int i;
    1261         1069 :   bool cfg_changed = false;
    1262              : 
    1263         1069 :   name = execute_cse_conv_1 (name, &cfg_changed);
    1264              : 
    1265         4212 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
    1266              :     {
    1267         3145 :       if (gimple_code (use_stmt) != GIMPLE_CALL
    1268         3145 :           || !gimple_call_lhs (use_stmt))
    1269         1823 :         continue;
    1270              : 
    1271         1322 :       switch (gimple_call_combined_fn (use_stmt))
    1272              :         {
    1273          462 :         CASE_CFN_COS:
    1274          462 :           seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1275          462 :           break;
    1276              : 
    1277          822 :         CASE_CFN_SIN:
    1278          822 :           seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1279          822 :           break;
    1280              : 
    1281            6 :         CASE_CFN_CEXPI:
    1282            6 :           seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
    1283            6 :           break;
    1284              : 
    1285           32 :         default:;
    1286           32 :           continue;
    1287              :         }
    1288              : 
    1289         1290 :       auto stmt_cfn = gimple_call_combined_fn (use_stmt);
    1290         1290 :       tree t = mathfn_built_in_type (stmt_cfn);
    1291         1290 :       if (!t)
    1292              :         {
    1293              :           /* It is possible to get IFN_{SIN,COS} calls, for which
    1294              :              mathfn_built_in_type will return NULL.  Those are normally only
    1295              :              present for vector operations.  We won't be able to CSE those
    1296              :              at the moment. */
    1297            2 :           gcc_checking_assert (internal_fn_p (stmt_cfn));
    1298              :           return false;
    1299              :         }
    1300              : 
    1301         1288 :       if (!type)
    1302              :         {
    1303         1067 :           type = t;
    1304         1067 :           t = TREE_TYPE (name);
    1305              :         }
    1306              :       /* This checks that NAME has the right type in the first round,
    1307              :          and, in subsequent rounds, that the built_in type is the same
    1308              :          type, or a compatible type.  */
    1309         1288 :       if (type != t && !types_compatible_p (type, t))
    1310              :         return false;
    1311            2 :     }
    1312         1067 :   if (seen_cos + seen_sin + seen_cexpi <= 1)
    1313              :     return false;
    1314              : 
    1315              :   /* Simply insert cexpi at the beginning of top_bb but not earlier than
    1316              :      the name def statement.  */
    1317          201 :   fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
    1318          201 :   if (!fndecl)
    1319              :     return false;
    1320          157 :   stmt = gimple_build_call (fndecl, 1, name);
    1321          157 :   res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), stmt, "sincostmp");
    1322          157 :   gimple_call_set_lhs (stmt, res);
    1323              : 
    1324          157 :   def_stmt = SSA_NAME_DEF_STMT (name);
    1325          157 :   if (!SSA_NAME_IS_DEFAULT_DEF (name)
    1326          127 :       && gimple_code (def_stmt) != GIMPLE_PHI
    1327          276 :       && gimple_bb (def_stmt) == top_bb)
    1328              :     {
    1329          119 :       gsi = gsi_for_stmt (def_stmt);
    1330          119 :       gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
    1331              :     }
    1332              :   else
    1333              :     {
    1334           38 :       gsi = gsi_after_labels (top_bb);
    1335           38 :       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    1336              :     }
    1337          157 :   sincos_stats.inserted++;
    1338              : 
    1339              :   /* And adjust the recorded old call sites.  */
    1340          471 :   for (i = 0; stmts.iterate (i, &use_stmt); ++i)
    1341              :     {
    1342          314 :       tree rhs = NULL;
    1343              : 
    1344          314 :       switch (gimple_call_combined_fn (use_stmt))
    1345              :         {
    1346          157 :         CASE_CFN_COS:
    1347          157 :           rhs = fold_build1 (REALPART_EXPR, type, res);
    1348          157 :           break;
    1349              : 
    1350          157 :         CASE_CFN_SIN:
    1351          157 :           rhs = fold_build1 (IMAGPART_EXPR, type, res);
    1352          157 :           break;
    1353              : 
    1354              :         CASE_CFN_CEXPI:
    1355              :           rhs = res;
    1356              :           break;
    1357              : 
    1358            0 :         default:;
    1359            0 :           gcc_unreachable ();
    1360              :         }
    1361              : 
    1362              :         /* Replace call with a copy.  */
    1363          314 :         stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs);
    1364              : 
    1365          314 :         gsi = gsi_for_stmt (use_stmt);
    1366          314 :         gsi_replace (&gsi, stmt, true);
    1367          314 :         if (gimple_purge_dead_eh_edges (gimple_bb (stmt)))
    1368            0 :           cfg_changed = true;
    1369              :     }
    1370              : 
    1371          157 :   return cfg_changed;
    1372         1069 : }
    1373              : 
    1374              : /* To evaluate powi(x,n), the floating point value x raised to the
    1375              :    constant integer exponent n, we use a hybrid algorithm that
    1376              :    combines the "window method" with look-up tables.  For an
    1377              :    introduction to exponentiation algorithms and "addition chains",
    1378              :    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
    1379              :    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
    1380              :    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
    1381              :    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
    1382              : 
    1383              : /* Provide a default value for POWI_MAX_MULTS, the maximum number of
    1384              :    multiplications to inline before calling the system library's pow
    1385              :    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
    1386              :    so this default never requires calling pow, powf or powl.  */
    1387              : 
    1388              : #ifndef POWI_MAX_MULTS
    1389              : #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
    1390              : #endif
    1391              : 
    1392              : /* The size of the "optimal power tree" lookup table.  All
    1393              :    exponents less than this value are simply looked up in the
    1394              :    powi_table below.  This threshold is also used to size the
    1395              :    cache of pseudo registers that hold intermediate results.  */
    1396              : #define POWI_TABLE_SIZE 256
    1397              : 
    1398              : /* The size, in bits of the window, used in the "window method"
    1399              :    exponentiation algorithm.  This is equivalent to a radix of
    1400              :    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
    1401              : #define POWI_WINDOW_SIZE 3
    1402              : 
    1403              : /* The following table is an efficient representation of an
    1404              :    "optimal power tree".  For each value, i, the corresponding
    1405              :    value, j, in the table states than an optimal evaluation
    1406              :    sequence for calculating pow(x,i) can be found by evaluating
    1407              :    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
    1408              :    100 integers is given in Knuth's "Seminumerical algorithms".  */
    1409              : 
    1410              : static const unsigned char powi_table[POWI_TABLE_SIZE] =
    1411              :   {
    1412              :       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
    1413              :       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
    1414              :       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
    1415              :      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
    1416              :      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
    1417              :      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
    1418              :      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
    1419              :      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
    1420              :      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
    1421              :      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
    1422              :      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
    1423              :      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
    1424              :      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
    1425              :      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
    1426              :      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
    1427              :      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
    1428              :      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
    1429              :      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
    1430              :      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
    1431              :      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
    1432              :      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
    1433              :      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
    1434              :      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
    1435              :      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
    1436              :      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
    1437              :     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
    1438              :     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
    1439              :     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
    1440              :     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
    1441              :     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
    1442              :     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
    1443              :     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
    1444              :   };
    1445              : 
    1446              : 
    1447              : /* Return the number of multiplications required to calculate
    1448              :    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
    1449              :    subroutine of powi_cost.  CACHE is an array indicating
    1450              :    which exponents have already been calculated.  */
    1451              : 
    1452              : static int
    1453         1120 : powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
    1454              : {
    1455              :   /* If we've already calculated this exponent, then this evaluation
    1456              :      doesn't require any additional multiplications.  */
    1457         1861 :   if (cache[n])
    1458         1120 :     return 0;
    1459              : 
    1460          741 :   cache[n] = true;
    1461          741 :   return powi_lookup_cost (n - powi_table[n], cache)
    1462          741 :          + powi_lookup_cost (powi_table[n], cache) + 1;
    1463              : }
    1464              : 
    1465              : /* Return the number of multiplications required to calculate
    1466              :    powi(x,n) for an arbitrary x, given the exponent N.  This
    1467              :    function needs to be kept in sync with powi_as_mults below.  */
    1468              : 
    1469              : static int
    1470          384 : powi_cost (HOST_WIDE_INT n)
    1471              : {
    1472          384 :   bool cache[POWI_TABLE_SIZE];
    1473          384 :   unsigned HOST_WIDE_INT digit;
    1474          384 :   unsigned HOST_WIDE_INT val;
    1475          384 :   int result;
    1476              : 
    1477          384 :   if (n == 0)
    1478              :     return 0;
    1479              : 
    1480              :   /* Ignore the reciprocal when calculating the cost.  */
    1481          379 :   val = absu_hwi (n);
    1482              : 
    1483              :   /* Initialize the exponent cache.  */
    1484          379 :   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
    1485          379 :   cache[1] = true;
    1486              : 
    1487          379 :   result = 0;
    1488              : 
    1489          379 :   while (val >= POWI_TABLE_SIZE)
    1490              :     {
    1491            0 :       if (val & 1)
    1492              :         {
    1493            0 :           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
    1494            0 :           result += powi_lookup_cost (digit, cache)
    1495            0 :                     + POWI_WINDOW_SIZE + 1;
    1496            0 :           val >>= POWI_WINDOW_SIZE;
    1497              :         }
    1498              :       else
    1499              :         {
    1500            0 :           val >>= 1;
    1501            0 :           result++;
    1502              :         }
    1503              :     }
    1504              : 
    1505          379 :   return result + powi_lookup_cost (val, cache);
    1506              : }
    1507              : 
    1508              : /* Recursive subroutine of powi_as_mults.  This function takes the
    1509              :    array, CACHE, of already calculated exponents and an exponent N and
    1510              :    returns a tree that corresponds to CACHE[1]**N, with type TYPE.  */
    1511              : 
    1512              : static tree
    1513         6242 : powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type,
    1514              :                  unsigned HOST_WIDE_INT n, tree *cache)
    1515              : {
    1516         6242 :   tree op0, op1, ssa_target;
    1517         6242 :   unsigned HOST_WIDE_INT digit;
    1518         6242 :   gassign *mult_stmt;
    1519              : 
    1520         6242 :   if (n < POWI_TABLE_SIZE && cache[n])
    1521              :     return cache[n];
    1522              : 
    1523         2209 :   ssa_target = make_temp_ssa_name (type, NULL, "powmult");
    1524              : 
    1525         2209 :   if (n < POWI_TABLE_SIZE)
    1526              :     {
    1527         2206 :       cache[n] = ssa_target;
    1528         2206 :       op0 = powi_as_mults_1 (gsi, loc, type, n - powi_table[n], cache);
    1529         2206 :       op1 = powi_as_mults_1 (gsi, loc, type, powi_table[n], cache);
    1530              :     }
    1531            3 :   else if (n & 1)
    1532              :     {
    1533            1 :       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
    1534            1 :       op0 = powi_as_mults_1 (gsi, loc, type, n - digit, cache);
    1535            1 :       op1 = powi_as_mults_1 (gsi, loc, type, digit, cache);
    1536              :     }
    1537              :   else
    1538              :     {
    1539            2 :       op0 = powi_as_mults_1 (gsi, loc, type, n >> 1, cache);
    1540            2 :       op1 = op0;
    1541              :     }
    1542              : 
    1543         2209 :   mult_stmt = gimple_build_assign (ssa_target, MULT_EXPR, op0, op1);
    1544         2209 :   gimple_set_location (mult_stmt, loc);
    1545         2209 :   gsi_insert_before (gsi, mult_stmt, GSI_SAME_STMT);
    1546              : 
    1547         2209 :   return ssa_target;
    1548              : }
    1549              : 
    1550              : /* Convert ARG0**N to a tree of multiplications of ARG0 with itself.
    1551              :    This function needs to be kept in sync with powi_cost above.  */
    1552              : 
    1553              : tree
    1554         1826 : powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
    1555              :                tree arg0, HOST_WIDE_INT n)
    1556              : {
    1557         1826 :   tree cache[POWI_TABLE_SIZE], result, type = TREE_TYPE (arg0);
    1558         1826 :   gassign *div_stmt;
    1559         1826 :   tree target;
    1560              : 
    1561         1826 :   if (n == 0)
    1562            0 :     return build_one_cst (type);
    1563              : 
    1564         1826 :   memset (cache, 0, sizeof (cache));
    1565         1826 :   cache[1] = arg0;
    1566              : 
    1567         1826 :   result = powi_as_mults_1 (gsi, loc, type, absu_hwi (n), cache);
    1568         1826 :   if (n >= 0)
    1569              :     return result;
    1570              : 
    1571              :   /* If the original exponent was negative, reciprocate the result.  */
    1572            8 :   target = make_temp_ssa_name (type, NULL, "powmult");
    1573            8 :   div_stmt = gimple_build_assign (target, RDIV_EXPR,
    1574              :                                   build_real (type, dconst1), result);
    1575            8 :   gimple_set_location (div_stmt, loc);
    1576            8 :   gsi_insert_before (gsi, div_stmt, GSI_SAME_STMT);
    1577              : 
    1578            8 :   return target;
    1579              : }
    1580              : 
    1581              : /* ARG0 and N are the two arguments to a powi builtin in GSI with
    1582              :    location info LOC.  If the arguments are appropriate, create an
    1583              :    equivalent sequence of statements prior to GSI using an optimal
    1584              :    number of multiplications, and return an expression holding the
    1585              :    result.  */
    1586              : 
    1587              : static tree
    1588          633 : gimple_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc,
    1589              :                             tree arg0, HOST_WIDE_INT n)
    1590              : {
    1591          633 :   if ((n >= -1 && n <= 2)
    1592          633 :       || (optimize_function_for_speed_p (cfun)
    1593          351 :           && powi_cost (n) <= POWI_MAX_MULTS))
    1594          625 :     return powi_as_mults (gsi, loc, arg0, n);
    1595              : 
    1596              :   return NULL_TREE;
    1597              : }
    1598              : 
    1599              : /* Build a gimple call statement that calls FN with argument ARG.
    1600              :    Set the lhs of the call statement to a fresh SSA name.  Insert the
    1601              :    statement prior to GSI's current position, and return the fresh
    1602              :    SSA name.  */
    1603              : 
    1604              : static tree
    1605           44 : build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc,
    1606              :                        tree fn, tree arg)
    1607              : {
    1608           44 :   gcall *call_stmt;
    1609           44 :   tree ssa_target;
    1610              : 
    1611           44 :   call_stmt = gimple_build_call (fn, 1, arg);
    1612           44 :   ssa_target = make_temp_ssa_name (TREE_TYPE (arg), NULL, "powroot");
    1613           44 :   gimple_set_lhs (call_stmt, ssa_target);
    1614           44 :   gimple_set_location (call_stmt, loc);
    1615           44 :   gsi_insert_before (gsi, call_stmt, GSI_SAME_STMT);
    1616              : 
    1617           44 :   return ssa_target;
    1618              : }
    1619              : 
    1620              : /* Build a gimple binary operation with the given CODE and arguments
    1621              :    ARG0, ARG1, assigning the result to a new SSA name for variable
    1622              :    TARGET.  Insert the statement prior to GSI's current position, and
    1623              :    return the fresh SSA name.*/
    1624              : 
    1625              : static tree
    1626         2643 : build_and_insert_binop (gimple_stmt_iterator *gsi, location_t loc,
    1627              :                         const char *name, enum tree_code code,
    1628              :                         tree arg0, tree arg1)
    1629              : {
    1630         2643 :   tree result = make_temp_ssa_name (TREE_TYPE (arg0), NULL, name);
    1631         2643 :   gassign *stmt = gimple_build_assign (result, code, arg0, arg1);
    1632         2643 :   gimple_set_location (stmt, loc);
    1633         2643 :   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    1634         2643 :   return result;
    1635              : }
    1636              : 
    1637              : /* Build a gimple assignment to cast VAL to TYPE.  Insert the statement
    1638              :    prior to GSI's current position, and return the fresh SSA name.  */
    1639              : 
    1640              : static tree
    1641        14571 : build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
    1642              :                        tree type, tree val)
    1643              : {
    1644            0 :   return gimple_convert (gsi, true, GSI_SAME_STMT, loc, type, val);
    1645              : }
    1646              : 
    1647              : struct pow_synth_sqrt_info
    1648              : {
    1649              :   bool *factors;
    1650              :   unsigned int deepest;
    1651              :   unsigned int num_mults;
    1652              : };
    1653              : 
    1654              : /* Return true iff the real value C can be represented as a
    1655              :    sum of powers of 0.5 up to N.  That is:
    1656              :    C == SUM<i from 1..N> (a[i]*(0.5**i)) where a[i] is either 0 or 1.
    1657              :    Record in INFO the various parameters of the synthesis algorithm such
    1658              :    as the factors a[i], the maximum 0.5 power and the number of
    1659              :    multiplications that will be required.  */
    1660              : 
    1661              : bool
    1662           33 : representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
    1663              :                                  struct pow_synth_sqrt_info *info)
    1664              : {
    1665           33 :   REAL_VALUE_TYPE factor = dconsthalf;
    1666           33 :   REAL_VALUE_TYPE remainder = c;
    1667              : 
    1668           33 :   info->deepest = 0;
    1669           33 :   info->num_mults = 0;
    1670           33 :   memset (info->factors, 0, n * sizeof (bool));
    1671              : 
    1672           97 :   for (unsigned i = 0; i < n; i++)
    1673              :     {
    1674           90 :       REAL_VALUE_TYPE res;
    1675              : 
    1676              :       /* If something inexact happened bail out now.  */
    1677           90 :       if (real_arithmetic (&res, MINUS_EXPR, &remainder, &factor))
    1678           26 :         return false;
    1679              : 
    1680              :       /* We have hit zero.  The number is representable as a sum
    1681              :          of powers of 0.5.  */
    1682           90 :       if (real_equal (&res, &dconst0))
    1683              :         {
    1684           26 :           info->factors[i] = true;
    1685           26 :           info->deepest = i + 1;
    1686           26 :           return true;
    1687              :         }
    1688           64 :       else if (!REAL_VALUE_NEGATIVE (res))
    1689              :         {
    1690           29 :           remainder = res;
    1691           29 :           info->factors[i] = true;
    1692           29 :           info->num_mults++;
    1693              :         }
    1694              :       else
    1695           35 :         info->factors[i] = false;
    1696              : 
    1697           64 :       real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
    1698              :     }
    1699              :   return false;
    1700              : }
    1701              : 
    1702              : /* Return the tree corresponding to FN being applied
    1703              :    to ARG N times at GSI and LOC.
    1704              :    Look up previous results from CACHE if need be.
    1705              :    cache[0] should contain just plain ARG i.e. FN applied to ARG 0 times.  */
    1706              : 
    1707              : static tree
    1708           63 : get_fn_chain (tree arg, unsigned int n, gimple_stmt_iterator *gsi,
    1709              :               tree fn, location_t loc, tree *cache)
    1710              : {
    1711           63 :   tree res = cache[n];
    1712           63 :   if (!res)
    1713              :     {
    1714           40 :       tree prev = get_fn_chain (arg, n - 1, gsi, fn, loc, cache);
    1715           40 :       res = build_and_insert_call (gsi, loc, fn, prev);
    1716           40 :       cache[n] = res;
    1717              :     }
    1718              : 
    1719           63 :   return res;
    1720              : }
    1721              : 
    1722              : /* Print to STREAM the repeated application of function FNAME to ARG
    1723              :    N times.  So, for FNAME = "foo", ARG = "x", N = 2 it would print:
    1724              :    "foo (foo (x))".  */
    1725              : 
    1726              : static void
    1727           36 : print_nested_fn (FILE* stream, const char *fname, const char* arg,
    1728              :                  unsigned int n)
    1729              : {
    1730           36 :   if (n == 0)
    1731           10 :     fprintf (stream, "%s", arg);
    1732              :   else
    1733              :     {
    1734           26 :       fprintf (stream, "%s (", fname);
    1735           26 :       print_nested_fn (stream, fname, arg, n - 1);
    1736           26 :       fprintf (stream, ")");
    1737              :     }
    1738           36 : }
    1739              : 
    1740              : /* Print to STREAM the fractional sequence of sqrt chains
    1741              :    applied to ARG, described by INFO.  Used for the dump file.  */
    1742              : 
    1743              : static void
    1744            7 : dump_fractional_sqrt_sequence (FILE *stream, const char *arg,
    1745              :                                 struct pow_synth_sqrt_info *info)
    1746              : {
    1747           29 :   for (unsigned int i = 0; i < info->deepest; i++)
    1748              :     {
    1749           22 :       bool is_set = info->factors[i];
    1750           22 :       if (is_set)
    1751              :         {
    1752           10 :           print_nested_fn (stream, "sqrt", arg, i + 1);
    1753           10 :           if (i != info->deepest - 1)
    1754            3 :             fprintf (stream, " * ");
    1755              :         }
    1756              :     }
    1757            7 : }
    1758              : 
    1759              : /* Print to STREAM a representation of raising ARG to an integer
    1760              :    power N.  Used for the dump file.  */
    1761              : 
    1762              : static void
    1763            7 : dump_integer_part (FILE *stream, const char* arg, HOST_WIDE_INT n)
    1764              : {
    1765            7 :   if (n > 1)
    1766            3 :     fprintf (stream, "powi (%s, " HOST_WIDE_INT_PRINT_DEC ")", arg, n);
    1767            4 :   else if (n == 1)
    1768            3 :     fprintf (stream, "%s", arg);
    1769            7 : }
    1770              : 
    1771              : /* Attempt to synthesize a POW[F] (ARG0, ARG1) call using chains of
    1772              :    square roots.  Place at GSI and LOC.  Limit the maximum depth
    1773              :    of the sqrt chains to MAX_DEPTH.  Return the tree holding the
    1774              :    result of the expanded sequence or NULL_TREE if the expansion failed.
    1775              : 
    1776              :    This routine assumes that ARG1 is a real number with a fractional part
    1777              :    (the integer exponent case will have been handled earlier in
    1778              :    gimple_expand_builtin_pow).
    1779              : 
    1780              :    For ARG1 > 0.0:
    1781              :    * For ARG1 composed of a whole part WHOLE_PART and a fractional part
    1782              :      FRAC_PART i.e. WHOLE_PART == floor (ARG1) and
    1783              :                     FRAC_PART == ARG1 - WHOLE_PART:
    1784              :      Produce POWI (ARG0, WHOLE_PART) * POW (ARG0, FRAC_PART) where
    1785              :      POW (ARG0, FRAC_PART) is expanded as a product of square root chains
    1786              :      if it can be expressed as such, that is if FRAC_PART satisfies:
    1787              :      FRAC_PART == <SUM from i = 1 until MAX_DEPTH> (a[i] * (0.5**i))
    1788              :      where integer a[i] is either 0 or 1.
    1789              : 
    1790              :      Example:
    1791              :      POW (x, 3.625) == POWI (x, 3) * POW (x, 0.625)
    1792              :        --> POWI (x, 3) * SQRT (x) * SQRT (SQRT (SQRT (x)))
    1793              : 
    1794              :    For ARG1 < 0.0 there are two approaches:
    1795              :    * (A) Expand to 1.0 / POW (ARG0, -ARG1) where POW (ARG0, -ARG1)
    1796              :          is calculated as above.
    1797              : 
    1798              :      Example:
    1799              :      POW (x, -5.625) == 1.0 / POW (x, 5.625)
    1800              :        -->  1.0 / (POWI (x, 5) * SQRT (x) * SQRT (SQRT (SQRT (x))))
    1801              : 
    1802              :    * (B) : WHOLE_PART := - ceil (abs (ARG1))
    1803              :            FRAC_PART  := ARG1 - WHOLE_PART
    1804              :      and expand to POW (x, FRAC_PART) / POWI (x, WHOLE_PART).
    1805              :      Example:
    1806              :      POW (x, -5.875) == POW (x, 0.125) / POWI (X, 6)
    1807              :        --> SQRT (SQRT (SQRT (x))) / (POWI (x, 6))
    1808              : 
    1809              :    For ARG1 < 0.0 we choose between (A) and (B) depending on
    1810              :    how many multiplications we'd have to do.
    1811              :    So, for the example in (B): POW (x, -5.875), if we were to
    1812              :    follow algorithm (A) we would produce:
    1813              :    1.0 / POWI (X, 5) * SQRT (X) * SQRT (SQRT (X)) * SQRT (SQRT (SQRT (X)))
    1814              :    which contains more multiplications than approach (B).
    1815              : 
    1816              :    Hopefully, this approach will eliminate potentially expensive POW library
    1817              :    calls when unsafe floating point math is enabled and allow the compiler to
    1818              :    further optimise the multiplies, square roots and divides produced by this
    1819              :    function.  */
    1820              : 
    1821              : static tree
    1822           25 : expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
    1823              :                      tree arg0, tree arg1, HOST_WIDE_INT max_depth)
    1824              : {
    1825           25 :   tree type = TREE_TYPE (arg0);
    1826           25 :   machine_mode mode = TYPE_MODE (type);
    1827           25 :   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
    1828           25 :   bool one_over = true;
    1829              : 
    1830           25 :   if (!sqrtfn)
    1831              :     return NULL_TREE;
    1832              : 
    1833           25 :   if (TREE_CODE (arg1) != REAL_CST)
    1834              :     return NULL_TREE;
    1835              : 
    1836           25 :   REAL_VALUE_TYPE exp_init = TREE_REAL_CST (arg1);
    1837              : 
    1838           25 :   gcc_assert (max_depth > 0);
    1839           25 :   tree *cache = XALLOCAVEC (tree, max_depth + 1);
    1840              : 
    1841           25 :   struct pow_synth_sqrt_info synth_info;
    1842           25 :   synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
    1843           25 :   synth_info.deepest = 0;
    1844           25 :   synth_info.num_mults = 0;
    1845              : 
    1846           25 :   bool neg_exp = REAL_VALUE_NEGATIVE (exp_init);
    1847           25 :   REAL_VALUE_TYPE exp = real_value_abs (&exp_init);
    1848              : 
    1849              :   /* The whole and fractional parts of exp.  */
    1850           25 :   REAL_VALUE_TYPE whole_part;
    1851           25 :   REAL_VALUE_TYPE frac_part;
    1852              : 
    1853           25 :   real_floor (&whole_part, mode, &exp);
    1854           25 :   real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
    1855              : 
    1856              : 
    1857           25 :   REAL_VALUE_TYPE ceil_whole = dconst0;
    1858           25 :   REAL_VALUE_TYPE ceil_fract = dconst0;
    1859              : 
    1860           25 :   if (neg_exp)
    1861              :     {
    1862           10 :       real_ceil (&ceil_whole, mode, &exp);
    1863           10 :       real_arithmetic (&ceil_fract, MINUS_EXPR, &ceil_whole, &exp);
    1864              :     }
    1865              : 
    1866           25 :   if (!representable_as_half_series_p (frac_part, max_depth, &synth_info))
    1867              :     return NULL_TREE;
    1868              : 
    1869              :   /* Check whether it's more profitable to not use 1.0 / ...  */
    1870           18 :   if (neg_exp)
    1871              :     {
    1872            8 :       struct pow_synth_sqrt_info alt_synth_info;
    1873            8 :       alt_synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
    1874            8 :       alt_synth_info.deepest = 0;
    1875            8 :       alt_synth_info.num_mults = 0;
    1876              : 
    1877            8 :       if (representable_as_half_series_p (ceil_fract, max_depth,
    1878              :                                            &alt_synth_info)
    1879            8 :           && alt_synth_info.deepest <= synth_info.deepest
    1880           16 :           && alt_synth_info.num_mults < synth_info.num_mults)
    1881              :         {
    1882            2 :           whole_part = ceil_whole;
    1883            2 :           frac_part = ceil_fract;
    1884            2 :           synth_info.deepest = alt_synth_info.deepest;
    1885            2 :           synth_info.num_mults = alt_synth_info.num_mults;
    1886            2 :           memcpy (synth_info.factors, alt_synth_info.factors,
    1887              :                   (max_depth + 1) * sizeof (bool));
    1888            2 :           one_over = false;
    1889              :         }
    1890              :     }
    1891              : 
    1892           18 :   HOST_WIDE_INT n = real_to_integer (&whole_part);
    1893           18 :   REAL_VALUE_TYPE cint;
    1894           18 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    1895              : 
    1896           18 :   if (!real_identical (&whole_part, &cint))
    1897              :     return NULL_TREE;
    1898              : 
    1899           18 :   if (powi_cost (n) + synth_info.num_mults > POWI_MAX_MULTS)
    1900              :     return NULL_TREE;
    1901              : 
    1902           18 :   memset (cache, 0, (max_depth + 1) * sizeof (tree));
    1903              : 
    1904           18 :   tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
    1905              : 
    1906              :   /* Calculate the integer part of the exponent.  */
    1907           18 :   if (n > 1)
    1908              :     {
    1909            6 :       integer_res = gimple_expand_builtin_powi (gsi, loc, arg0, n);
    1910            6 :       if (!integer_res)
    1911              :         return NULL_TREE;
    1912              :     }
    1913              : 
    1914           18 :   if (dump_file)
    1915              :     {
    1916            7 :       char string[64];
    1917              : 
    1918            7 :       real_to_decimal (string, &exp_init, sizeof (string), 0, 1);
    1919            7 :       fprintf (dump_file, "synthesizing pow (x, %s) as:\n", string);
    1920              : 
    1921            7 :       if (neg_exp)
    1922              :         {
    1923            2 :           if (one_over)
    1924              :             {
    1925            1 :               fprintf (dump_file, "1.0 / (");
    1926            1 :               dump_integer_part (dump_file, "x", n);
    1927            1 :               if (n > 0)
    1928            1 :                 fprintf (dump_file, " * ");
    1929            1 :               dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1930            1 :               fprintf (dump_file, ")");
    1931              :             }
    1932              :           else
    1933              :             {
    1934            1 :               dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1935            1 :               fprintf (dump_file, " / (");
    1936            1 :               dump_integer_part (dump_file, "x", n);
    1937            1 :               fprintf (dump_file, ")");
    1938              :             }
    1939              :         }
    1940              :       else
    1941              :         {
    1942            5 :           dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
    1943            5 :           if (n > 0)
    1944            4 :             fprintf (dump_file, " * ");
    1945            5 :           dump_integer_part (dump_file, "x", n);
    1946              :         }
    1947              : 
    1948            7 :       fprintf (dump_file, "\ndeepest sqrt chain: %d\n", synth_info.deepest);
    1949              :     }
    1950              : 
    1951              : 
    1952           18 :   tree fract_res = NULL_TREE;
    1953           18 :   cache[0] = arg0;
    1954              : 
    1955              :   /* Calculate the fractional part of the exponent.  */
    1956           58 :   for (unsigned i = 0; i < synth_info.deepest; i++)
    1957              :     {
    1958           40 :       if (synth_info.factors[i])
    1959              :         {
    1960           23 :           tree sqrt_chain = get_fn_chain (arg0, i + 1, gsi, sqrtfn, loc, cache);
    1961              : 
    1962           23 :           if (!fract_res)
    1963              :               fract_res = sqrt_chain;
    1964              : 
    1965              :           else
    1966            5 :             fract_res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1967              :                                            fract_res, sqrt_chain);
    1968              :         }
    1969              :     }
    1970              : 
    1971           18 :   tree res = NULL_TREE;
    1972              : 
    1973           18 :   if (neg_exp)
    1974              :     {
    1975            8 :       if (one_over)
    1976              :         {
    1977            6 :           if (n > 0)
    1978            4 :             res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1979              :                                            fract_res, integer_res);
    1980              :           else
    1981              :             res = fract_res;
    1982              : 
    1983            6 :           res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
    1984              :                                           build_real (type, dconst1), res);
    1985              :         }
    1986              :       else
    1987              :         {
    1988            2 :           res = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
    1989              :                                          fract_res, integer_res);
    1990              :         }
    1991              :     }
    1992              :   else
    1993           10 :     res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    1994              :                                    fract_res, integer_res);
    1995              :   return res;
    1996              : }
    1997              : 
    1998              : /* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
    1999              :    with location info LOC.  If possible, create an equivalent and
    2000              :    less expensive sequence of statements prior to GSI, and return an
    2001              :    expression holding the result.  */
    2002              : 
    2003              : static tree
    2004          604 : gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
    2005              :                            tree arg0, tree arg1)
    2006              : {
    2007          604 :   REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
    2008          604 :   REAL_VALUE_TYPE c2, dconst3;
    2009          604 :   HOST_WIDE_INT n;
    2010          604 :   tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
    2011          604 :   machine_mode mode;
    2012          604 :   bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
    2013          604 :   bool hw_sqrt_exists, c_is_int, c2_is_int;
    2014              : 
    2015          604 :   dconst1_4 = dconst1;
    2016          604 :   SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
    2017              : 
    2018              :   /* If the exponent isn't a constant, there's nothing of interest
    2019              :      to be done.  */
    2020          604 :   if (TREE_CODE (arg1) != REAL_CST)
    2021              :     return NULL_TREE;
    2022              : 
    2023              :   /* Don't perform the operation if flag_signaling_nans is on
    2024              :      and the operand is a signaling NaN.  */
    2025          363 :   if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
    2026          363 :       && ((TREE_CODE (arg0) == REAL_CST
    2027            0 :            && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0)))
    2028            1 :           || REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1))))
    2029              :     return NULL_TREE;
    2030              : 
    2031          363 :   if (flag_errno_math)
    2032              :     return NULL_TREE;
    2033              : 
    2034              :   /* If the exponent is equivalent to an integer, expand to an optimal
    2035              :      multiplication sequence when profitable.  */
    2036           75 :   c = TREE_REAL_CST (arg1);
    2037           75 :   n = real_to_integer (&c);
    2038           75 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2039           75 :   c_is_int = real_identical (&c, &cint);
    2040              : 
    2041           75 :   if (c_is_int
    2042           75 :       && ((n >= -1 && n <= 2)
    2043           21 :           || (flag_unsafe_math_optimizations
    2044           11 :               && speed_p
    2045           11 :               && powi_cost (n) <= POWI_MAX_MULTS)))
    2046           30 :     return gimple_expand_builtin_powi (gsi, loc, arg0, n);
    2047              : 
    2048              :   /* Attempt various optimizations using sqrt and cbrt.  */
    2049           45 :   type = TREE_TYPE (arg0);
    2050           45 :   mode = TYPE_MODE (type);
    2051           45 :   sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
    2052              : 
    2053              :   /* Optimize pow(x,0.5) = sqrt(x).  This replacement is always safe
    2054              :      unless signed zeros must be maintained.  pow(-0,0.5) = +0, while
    2055              :      sqrt(-0) = -0.  */
    2056           45 :   if (sqrtfn
    2057           45 :       && real_equal (&c, &dconsthalf)
    2058           52 :       && !HONOR_SIGNED_ZEROS (mode))
    2059            0 :     return build_and_insert_call (gsi, loc, sqrtfn, arg0);
    2060              : 
    2061           45 :   hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing;
    2062              : 
    2063              :   /* Optimize pow(x,1./3.) = cbrt(x).  This requires unsafe math
    2064              :      optimizations since 1./3. is not exactly representable.  If x
    2065              :      is negative and finite, the correct value of pow(x,1./3.) is
    2066              :      a NaN with the "invalid" exception raised, because the value
    2067              :      of 1./3. actually has an even denominator.  The correct value
    2068              :      of cbrt(x) is a negative real value.  */
    2069           45 :   cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
    2070           45 :   dconst1_3 = real_value_truncate (mode, dconst_third ());
    2071              : 
    2072           45 :   if (flag_unsafe_math_optimizations
    2073           25 :       && cbrtfn
    2074           25 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2075           70 :       && real_equal (&c, &dconst1_3))
    2076            0 :     return build_and_insert_call (gsi, loc, cbrtfn, arg0);
    2077              : 
    2078              :   /* Optimize pow(x,1./6.) = cbrt(sqrt(x)).  Don't do this optimization
    2079              :      if we don't have a hardware sqrt insn.  */
    2080           45 :   dconst1_6 = dconst1_3;
    2081           45 :   SET_REAL_EXP (&dconst1_6, REAL_EXP (&dconst1_6) - 1);
    2082              : 
    2083           45 :   if (flag_unsafe_math_optimizations
    2084           25 :       && sqrtfn
    2085           25 :       && cbrtfn
    2086           25 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2087              :       && speed_p
    2088           25 :       && hw_sqrt_exists
    2089           70 :       && real_equal (&c, &dconst1_6))
    2090              :     {
    2091              :       /* sqrt(x)  */
    2092            0 :       sqrt_arg0 = build_and_insert_call (gsi, loc, sqrtfn, arg0);
    2093              : 
    2094              :       /* cbrt(sqrt(x))  */
    2095            0 :       return build_and_insert_call (gsi, loc, cbrtfn, sqrt_arg0);
    2096              :     }
    2097              : 
    2098              : 
    2099              :   /* Attempt to expand the POW as a product of square root chains.
    2100              :      Expand the 0.25 case even when optimising for size.  */
    2101           45 :   if (flag_unsafe_math_optimizations
    2102           25 :       && sqrtfn
    2103           25 :       && hw_sqrt_exists
    2104           25 :       && (speed_p || real_equal (&c, &dconst1_4))
    2105           70 :       && !HONOR_SIGNED_ZEROS (mode))
    2106              :     {
    2107           75 :       unsigned int max_depth = speed_p
    2108           25 :                                 ? param_max_pow_sqrt_depth
    2109              :                                 : 2;
    2110              : 
    2111           25 :       tree expand_with_sqrts
    2112           25 :         = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth);
    2113              : 
    2114           25 :       if (expand_with_sqrts)
    2115              :         return expand_with_sqrts;
    2116              :     }
    2117              : 
    2118           27 :   real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
    2119           27 :   n = real_to_integer (&c2);
    2120           27 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2121           27 :   c2_is_int = real_identical (&c2, &cint);
    2122              : 
    2123              :   /* Optimize pow(x,c), where 3c = n for some nonzero integer n, into
    2124              : 
    2125              :      powi(x, n/3) * powi(cbrt(x), n%3),                    n > 0;
    2126              :      1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)),  n < 0.
    2127              : 
    2128              :      Do not calculate the first factor when n/3 = 0.  As cbrt(x) is
    2129              :      different from pow(x, 1./3.) due to rounding and behavior with
    2130              :      negative x, we need to constrain this transformation to unsafe
    2131              :      math and positive x or finite math.  */
    2132           27 :   real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
    2133           27 :   real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
    2134           27 :   real_round (&c2, mode, &c2);
    2135           27 :   n = real_to_integer (&c2);
    2136           27 :   real_from_integer (&cint, VOIDmode, n, SIGNED);
    2137           27 :   real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
    2138           27 :   real_convert (&c2, mode, &c2);
    2139              : 
    2140           27 :   if (flag_unsafe_math_optimizations
    2141            7 :       && cbrtfn
    2142            7 :       && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
    2143            7 :       && real_identical (&c2, &c)
    2144            4 :       && !c2_is_int
    2145            4 :       && optimize_function_for_speed_p (cfun)
    2146           31 :       && powi_cost (n / 3) <= POWI_MAX_MULTS)
    2147              :     {
    2148            4 :       tree powi_x_ndiv3 = NULL_TREE;
    2149              : 
    2150              :       /* Attempt to fold powi(arg0, abs(n/3)) into multiplies.  If not
    2151              :          possible or profitable, give up.  Skip the degenerate case when
    2152              :          abs(n) < 3, where the result is always 1.  */
    2153            4 :       if (absu_hwi (n) >= 3)
    2154              :         {
    2155            4 :           powi_x_ndiv3 = gimple_expand_builtin_powi (gsi, loc, arg0,
    2156              :                                                      abs_hwi (n / 3));
    2157            4 :           if (!powi_x_ndiv3)
    2158              :             return NULL_TREE;
    2159              :         }
    2160              : 
    2161              :       /* Calculate powi(cbrt(x), n%3).  Don't use gimple_expand_builtin_powi
    2162              :          as that creates an unnecessary variable.  Instead, just produce
    2163              :          either cbrt(x) or cbrt(x) * cbrt(x).  */
    2164            4 :       cbrt_x = build_and_insert_call (gsi, loc, cbrtfn, arg0);
    2165              : 
    2166            4 :       if (absu_hwi (n) % 3 == 1)
    2167              :         powi_cbrt_x = cbrt_x;
    2168              :       else
    2169            2 :         powi_cbrt_x = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    2170              :                                               cbrt_x, cbrt_x);
    2171              : 
    2172              :       /* Multiply the two subexpressions, unless powi(x,abs(n)/3) = 1.  */
    2173            4 :       if (absu_hwi (n) < 3)
    2174              :         result = powi_cbrt_x;
    2175              :       else
    2176            4 :         result = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
    2177              :                                          powi_x_ndiv3, powi_cbrt_x);
    2178              : 
    2179              :       /* If n is negative, reciprocate the result.  */
    2180            4 :       if (n < 0)
    2181            1 :         result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
    2182              :                                          build_real (type, dconst1), result);
    2183              : 
    2184              :       return result;
    2185              :     }
    2186              : 
    2187              :   /* No optimizations succeeded.  */
    2188              :   return NULL_TREE;
    2189              : }
    2190              : 
    2191              : /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
    2192              :    on the SSA_NAME argument of each of them.  */
    2193              : 
    2194              : namespace {
    2195              : 
    2196              : const pass_data pass_data_cse_sincos =
    2197              : {
    2198              :   GIMPLE_PASS, /* type */
    2199              :   "sincos", /* name */
    2200              :   OPTGROUP_NONE, /* optinfo_flags */
    2201              :   TV_TREE_SINCOS, /* tv_id */
    2202              :   PROP_ssa, /* properties_required */
    2203              :   0, /* properties_provided */
    2204              :   0, /* properties_destroyed */
    2205              :   0, /* todo_flags_start */
    2206              :   TODO_update_ssa, /* todo_flags_finish */
    2207              : };
    2208              : 
    2209              : class pass_cse_sincos : public gimple_opt_pass
    2210              : {
    2211              : public:
    2212       294587 :   pass_cse_sincos (gcc::context *ctxt)
    2213       589174 :     : gimple_opt_pass (pass_data_cse_sincos, ctxt)
    2214              :   {}
    2215              : 
    2216              :   /* opt_pass methods: */
    2217      1062413 :   bool gate (function *) final override
    2218              :     {
    2219      1062413 :       return optimize;
    2220              :     }
    2221              : 
    2222              :   unsigned int execute (function *) final override;
    2223              : 
    2224              : }; // class pass_cse_sincos
    2225              : 
    2226              : unsigned int
    2227      1062375 : pass_cse_sincos::execute (function *fun)
    2228              : {
    2229      1062375 :   basic_block bb;
    2230      1062375 :   bool cfg_changed = false;
    2231              : 
    2232      1062375 :   calculate_dominance_info (CDI_DOMINATORS);
    2233      1062375 :   memset (&sincos_stats, 0, sizeof (sincos_stats));
    2234              : 
    2235     11260539 :   FOR_EACH_BB_FN (bb, fun)
    2236              :     {
    2237     10198164 :       gimple_stmt_iterator gsi;
    2238              : 
    2239    100430201 :       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    2240              :         {
    2241     90232037 :           gimple *stmt = gsi_stmt (gsi);
    2242              : 
    2243     90232037 :           if (is_gimple_call (stmt)
    2244     90232037 :               && gimple_call_lhs (stmt))
    2245              :             {
    2246      2062988 :               tree arg;
    2247      2062988 :               switch (gimple_call_combined_fn (stmt))
    2248              :                 {
    2249         1069 :                 CASE_CFN_COS:
    2250         1069 :                 CASE_CFN_SIN:
    2251         1069 :                 CASE_CFN_CEXPI:
    2252         1069 :                   arg = gimple_call_arg (stmt, 0);
    2253              :                   /* Make sure we have either sincos or cexp.  */
    2254         1069 :                   if (!targetm.libc_has_function (function_c99_math_complex,
    2255         1069 :                                                   TREE_TYPE (arg))
    2256         1069 :                       && !targetm.libc_has_function (function_sincos,
    2257            0 :                                                      TREE_TYPE (arg)))
    2258              :                     break;
    2259              : 
    2260         1069 :                   if (TREE_CODE (arg) == SSA_NAME)
    2261         1069 :                     cfg_changed |= execute_cse_sincos_1 (arg);
    2262              :                   break;
    2263              :                 default:
    2264              :                   break;
    2265              :                 }
    2266              :             }
    2267              :         }
    2268              :     }
    2269              : 
    2270      1062375 :   statistics_counter_event (fun, "sincos statements inserted",
    2271              :                             sincos_stats.inserted);
    2272      1062375 :   statistics_counter_event (fun, "conv statements removed",
    2273              :                             sincos_stats.conv_removed);
    2274              : 
    2275      1062375 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    2276              : }
    2277              : 
    2278              : } // anon namespace
    2279              : 
    2280              : gimple_opt_pass *
    2281       294587 : make_pass_cse_sincos (gcc::context *ctxt)
    2282              : {
    2283       294587 :   return new pass_cse_sincos (ctxt);
    2284              : }
    2285              : 
    2286              : /* Expand powi(x,n) into an optimal number of multiplies, when n is a
    2287              :    constant.  */
    2288              : namespace {
    2289              : 
    2290              : const pass_data pass_data_expand_pow =
    2291              : {
    2292              :   GIMPLE_PASS, /* type */
    2293              :   "pow", /* name */
    2294              :   OPTGROUP_NONE, /* optinfo_flags */
    2295              :   TV_TREE_POW, /* tv_id */
    2296              :   PROP_ssa, /* properties_required */
    2297              :   PROP_gimple_opt_math, /* properties_provided */
    2298              :   0, /* properties_destroyed */
    2299              :   0, /* todo_flags_start */
    2300              :   TODO_update_ssa, /* todo_flags_finish */
    2301              : };
    2302              : 
    2303              : class pass_expand_pow : public gimple_opt_pass
    2304              : {
    2305              : public:
    2306       294587 :   pass_expand_pow (gcc::context *ctxt)
    2307       589174 :     : gimple_opt_pass (pass_data_expand_pow, ctxt)
    2308              :   {}
    2309              : 
    2310              :   /* opt_pass methods: */
    2311      1062413 :   bool gate (function *) final override
    2312              :     {
    2313      1062413 :       return optimize;
    2314              :     }
    2315              : 
    2316              :   unsigned int execute (function *) final override;
    2317              : 
    2318              : }; // class pass_expand_pow
    2319              : 
    2320              : unsigned int
    2321      1062408 : pass_expand_pow::execute (function *fun)
    2322              : {
    2323      1062408 :   basic_block bb;
    2324      1062408 :   bool cfg_changed = false;
    2325              : 
    2326      1062408 :   calculate_dominance_info (CDI_DOMINATORS);
    2327              : 
    2328     11399283 :   FOR_EACH_BB_FN (bb, fun)
    2329              :     {
    2330     10336875 :       gimple_stmt_iterator gsi;
    2331     10336875 :       bool cleanup_eh = false;
    2332              : 
    2333     98153750 :       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    2334              :         {
    2335     87816875 :           gimple *stmt = gsi_stmt (gsi);
    2336              : 
    2337              :           /* Only the last stmt in a bb could throw, no need to call
    2338              :              gimple_purge_dead_eh_edges if we change something in the middle
    2339              :              of a basic block.  */
    2340     87816875 :           cleanup_eh = false;
    2341              : 
    2342     87816875 :           if (is_gimple_call (stmt)
    2343     87816875 :               && gimple_call_lhs (stmt))
    2344              :             {
    2345      2036974 :               tree arg0, arg1, result;
    2346      2036974 :               HOST_WIDE_INT n;
    2347      2036974 :               location_t loc;
    2348              : 
    2349      2036974 :               switch (gimple_call_combined_fn (stmt))
    2350              :                 {
    2351          604 :                 CASE_CFN_POW:
    2352          604 :                   arg0 = gimple_call_arg (stmt, 0);
    2353          604 :                   arg1 = gimple_call_arg (stmt, 1);
    2354              : 
    2355          604 :                   loc = gimple_location (stmt);
    2356          604 :                   result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
    2357              : 
    2358          604 :                   if (result)
    2359              :                     {
    2360           52 :                       tree lhs = gimple_get_lhs (stmt);
    2361           52 :                       gassign *new_stmt = gimple_build_assign (lhs, result);
    2362           52 :                       gimple_set_location (new_stmt, loc);
    2363           52 :                       unlink_stmt_vdef (stmt);
    2364           52 :                       gsi_replace (&gsi, new_stmt, true);
    2365           52 :                       cleanup_eh = true;
    2366          104 :                       if (gimple_vdef (stmt))
    2367            0 :                         release_ssa_name (gimple_vdef (stmt));
    2368              :                     }
    2369              :                   break;
    2370              : 
    2371          804 :                 CASE_CFN_POWI:
    2372          804 :                   arg0 = gimple_call_arg (stmt, 0);
    2373          804 :                   arg1 = gimple_call_arg (stmt, 1);
    2374          804 :                   loc = gimple_location (stmt);
    2375              : 
    2376          804 :                   if (real_minus_onep (arg0))
    2377              :                     {
    2378            0 :                       tree t0, t1, cond, one, minus_one;
    2379            0 :                       gassign *stmt;
    2380              : 
    2381            0 :                       t0 = TREE_TYPE (arg0);
    2382            0 :                       t1 = TREE_TYPE (arg1);
    2383            0 :                       one = build_real (t0, dconst1);
    2384            0 :                       minus_one = build_real (t0, dconstm1);
    2385              : 
    2386            0 :                       cond = make_temp_ssa_name (t1, NULL, "powi_cond");
    2387            0 :                       stmt = gimple_build_assign (cond, BIT_AND_EXPR,
    2388              :                                                   arg1, build_int_cst (t1, 1));
    2389            0 :                       gimple_set_location (stmt, loc);
    2390            0 :                       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    2391              : 
    2392            0 :                       result = make_temp_ssa_name (t0, NULL, "powi");
    2393            0 :                       stmt = gimple_build_assign (result, COND_EXPR, cond,
    2394              :                                                   minus_one, one);
    2395            0 :                       gimple_set_location (stmt, loc);
    2396            0 :                       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    2397              :                     }
    2398              :                   else
    2399              :                     {
    2400          804 :                       if (!tree_fits_shwi_p (arg1))
    2401              :                         break;
    2402              : 
    2403          593 :                       n = tree_to_shwi (arg1);
    2404          593 :                       result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
    2405              :                     }
    2406              : 
    2407          593 :                   if (result)
    2408              :                     {
    2409          585 :                       tree lhs = gimple_get_lhs (stmt);
    2410          585 :                       gassign *new_stmt = gimple_build_assign (lhs, result);
    2411          585 :                       gimple_set_location (new_stmt, loc);
    2412          585 :                       unlink_stmt_vdef (stmt);
    2413          585 :                       gsi_replace (&gsi, new_stmt, true);
    2414          585 :                       cleanup_eh = true;
    2415     87817460 :                       if (gimple_vdef (stmt))
    2416            0 :                         release_ssa_name (gimple_vdef (stmt));
    2417              :                     }
    2418              :                   break;
    2419              : 
    2420          211 :                 default:;
    2421              :                 }
    2422              :             }
    2423              :         }
    2424     10336875 :       if (cleanup_eh)
    2425            3 :         cfg_changed |= gimple_purge_dead_eh_edges (bb);
    2426              :     }
    2427              : 
    2428      1062408 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    2429              : }
    2430              : 
    2431              : } // anon namespace
    2432              : 
    2433              : gimple_opt_pass *
    2434       294587 : make_pass_expand_pow (gcc::context *ctxt)
    2435              : {
    2436       294587 :   return new pass_expand_pow (ctxt);
    2437              : }
    2438              : 
    2439              : /* Return true if stmt is a type conversion operation that can be stripped
    2440              :    when used in a widening multiply operation.  */
    2441              : static bool
    2442       512752 : widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
    2443              : {
    2444       512752 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    2445              : 
    2446       512752 :   if (TREE_CODE (result_type) == INTEGER_TYPE)
    2447              :     {
    2448       512752 :       tree op_type;
    2449       512752 :       tree inner_op_type;
    2450              : 
    2451       512752 :       if (!CONVERT_EXPR_CODE_P (rhs_code))
    2452              :         return false;
    2453              : 
    2454       200185 :       op_type = TREE_TYPE (gimple_assign_lhs (stmt));
    2455              : 
    2456              :       /* If the type of OP has the same precision as the result, then
    2457              :          we can strip this conversion.  The multiply operation will be
    2458              :          selected to create the correct extension as a by-product.  */
    2459       200185 :       if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type))
    2460              :         return true;
    2461              : 
    2462              :       /* We can also strip a conversion if it preserves the signed-ness of
    2463              :          the operation and doesn't narrow the range.  */
    2464         1168 :       inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
    2465              : 
    2466              :       /* If the inner-most type is unsigned, then we can strip any
    2467              :          intermediate widening operation.  If it's signed, then the
    2468              :          intermediate widening operation must also be signed.  */
    2469         1168 :       if ((TYPE_UNSIGNED (inner_op_type)
    2470         1164 :            || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type))
    2471         2332 :           && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type))
    2472              :         return true;
    2473              : 
    2474         1165 :       return false;
    2475              :     }
    2476              : 
    2477            0 :   return rhs_code == FIXED_CONVERT_EXPR;
    2478              : }
    2479              : 
    2480              : /* Return true if RHS is a suitable operand for a widening multiplication,
    2481              :    assuming a target type of TYPE.
    2482              :    There are two cases:
    2483              : 
    2484              :      - RHS makes some value at least twice as wide.  Store that value
    2485              :        in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.
    2486              : 
    2487              :      - RHS is an integer constant.  Store that value in *NEW_RHS_OUT if so,
    2488              :        but leave *TYPE_OUT untouched.  */
    2489              : 
    2490              : static bool
    2491       949643 : is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
    2492              :                         tree *new_rhs_out)
    2493              : {
    2494       949643 :   gimple *stmt;
    2495       949643 :   tree type1, rhs1;
    2496              : 
    2497       949643 :   if (TREE_CODE (rhs) == SSA_NAME)
    2498              :     {
    2499              :       /* Use tree_non_zero_bits to see if this operand is zero_extended
    2500              :          for unsigned widening multiplications or non-negative for
    2501              :          signed widening multiplications.  */
    2502       790106 :       if (TREE_CODE (type) == INTEGER_TYPE
    2503       790106 :           && (TYPE_PRECISION (type) & 1) == 0
    2504      1580212 :           && int_mode_for_size (TYPE_PRECISION (type) / 2, 1).exists ())
    2505              :         {
    2506       784140 :           unsigned int prec = TYPE_PRECISION (type);
    2507       784140 :           unsigned int hprec = prec / 2;
    2508       784140 :           wide_int bits = wide_int::from (tree_nonzero_bits (rhs), prec,
    2509      1568280 :                                           TYPE_SIGN (TREE_TYPE (rhs)));
    2510       784140 :           if (TYPE_UNSIGNED (type)
    2511      1338111 :               && wi::bit_and (bits, wi::mask (hprec, true, prec)) == 0)
    2512              :             {
    2513       135626 :               *type_out = build_nonstandard_integer_type (hprec, true);
    2514              :               /* X & MODE_MASK can be simplified to (T)X.  */
    2515       135626 :               stmt = SSA_NAME_DEF_STMT (rhs);
    2516       271252 :               if (is_gimple_assign (stmt)
    2517       120918 :                   && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
    2518        12100 :                   && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
    2519       159226 :                   && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
    2520        11800 :                                      prec, TYPE_SIGN (TREE_TYPE (rhs)))
    2521       171026 :                      == wi::mask (hprec, false, prec))
    2522         9858 :                 *new_rhs_out = gimple_assign_rhs1 (stmt);
    2523              :               else
    2524              :                 *new_rhs_out = rhs;
    2525       135626 :               return true;
    2526              :             }
    2527       648514 :           else if (!TYPE_UNSIGNED (type)
    2528       878683 :                    && wi::bit_and (bits, wi::mask (hprec - 1, true, prec)) == 0)
    2529              :             {
    2530        25347 :               *type_out = build_nonstandard_integer_type (hprec, false);
    2531        25347 :               *new_rhs_out = rhs;
    2532        25347 :               return true;
    2533              :             }
    2534       784140 :         }
    2535              : 
    2536       629133 :       stmt = SSA_NAME_DEF_STMT (rhs);
    2537       629133 :       if (is_gimple_assign (stmt))
    2538              :         {
    2539              : 
    2540       512752 :           if (widening_mult_conversion_strippable_p (type, stmt))
    2541              :             {
    2542       199020 :               rhs1 = gimple_assign_rhs1 (stmt);
    2543              : 
    2544       199020 :               if (TREE_CODE (rhs1) == INTEGER_CST)
    2545              :                 {
    2546            0 :                   *new_rhs_out = rhs1;
    2547            0 :                   *type_out = NULL;
    2548            0 :                   return true;
    2549              :                 }
    2550              :             }
    2551              :           else
    2552              :             rhs1 = rhs;
    2553              :         }
    2554              :       else
    2555              :         rhs1 = rhs;
    2556              : 
    2557       629133 :       type1 = TREE_TYPE (rhs1);
    2558              : 
    2559       629133 :       if (TREE_CODE (type1) != TREE_CODE (type)
    2560       629133 :           || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
    2561              :         return false;
    2562              : 
    2563        63464 :       *new_rhs_out = rhs1;
    2564        63464 :       *type_out = type1;
    2565        63464 :       return true;
    2566              :     }
    2567              : 
    2568       159537 :   if (TREE_CODE (rhs) == INTEGER_CST)
    2569              :     {
    2570       159537 :       *new_rhs_out = rhs;
    2571       159537 :       *type_out = NULL;
    2572       159537 :       return true;
    2573              :     }
    2574              : 
    2575              :   return false;
    2576              : }
    2577              : 
    2578              : /* Return true if STMT performs a widening multiplication, assuming the
    2579              :    output type is TYPE.  If so, store the unwidened types of the operands
    2580              :    in *TYPE1_OUT and *TYPE2_OUT respectively.  Also fill *RHS1_OUT and
    2581              :    *RHS2_OUT such that converting those operands to types *TYPE1_OUT
    2582              :    and *TYPE2_OUT would give the operands of the multiplication.  */
    2583              : 
    2584              : static bool
    2585       754731 : is_widening_mult_p (gimple *stmt,
    2586              :                     tree *type1_out, tree *rhs1_out,
    2587              :                     tree *type2_out, tree *rhs2_out)
    2588              : {
    2589       754731 :   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
    2590              : 
    2591       754731 :   if (TREE_CODE (type) == INTEGER_TYPE)
    2592              :     {
    2593       754731 :       if (TYPE_OVERFLOW_TRAPS (type))
    2594              :         return false;
    2595              :     }
    2596            0 :   else if (TREE_CODE (type) != FIXED_POINT_TYPE)
    2597              :     return false;
    2598              : 
    2599       754702 :   if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
    2600              :                                rhs1_out))
    2601              :     return false;
    2602              : 
    2603       194941 :   if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
    2604              :                                rhs2_out))
    2605              :     return false;
    2606              : 
    2607       189033 :   if (*type1_out == NULL)
    2608              :     {
    2609            0 :       if (*type2_out == NULL || !int_fits_type_p (*rhs1_out, *type2_out))
    2610              :         return false;
    2611            0 :       *type1_out = *type2_out;
    2612              :     }
    2613              : 
    2614       189033 :   if (*type2_out == NULL)
    2615              :     {
    2616       159537 :       if (!int_fits_type_p (*rhs2_out, *type1_out))
    2617              :         return false;
    2618       156330 :       *type2_out = *type1_out;
    2619              :     }
    2620              : 
    2621              :   /* Ensure that the larger of the two operands comes first. */
    2622       185826 :   if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out))
    2623              :     {
    2624           70 :       std::swap (*type1_out, *type2_out);
    2625           70 :       std::swap (*rhs1_out, *rhs2_out);
    2626              :     }
    2627              : 
    2628              :   return true;
    2629              : }
    2630              : 
    2631              : /* Check to see if the CALL statement is an invocation of copysign
    2632              :    with 1. being the first argument.  */
    2633              : static bool
    2634       197277 : is_copysign_call_with_1 (gimple *call)
    2635              : {
    2636       197277 :   gcall *c = dyn_cast <gcall *> (call);
    2637         5113 :   if (! c)
    2638              :     return false;
    2639              : 
    2640         5113 :   enum combined_fn code = gimple_call_combined_fn (c);
    2641              : 
    2642         5113 :   if (code == CFN_LAST)
    2643              :     return false;
    2644              : 
    2645         4083 :   if (builtin_fn_p (code))
    2646              :     {
    2647         1030 :       switch (as_builtin_fn (code))
    2648              :         {
    2649           30 :         CASE_FLT_FN (BUILT_IN_COPYSIGN):
    2650           30 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
    2651           30 :           return real_onep (gimple_call_arg (c, 0));
    2652              :         default:
    2653              :           return false;
    2654              :         }
    2655              :     }
    2656              : 
    2657         3053 :   if (internal_fn_p (code))
    2658              :     {
    2659         3053 :       switch (as_internal_fn (code))
    2660              :         {
    2661           24 :         case IFN_COPYSIGN:
    2662           24 :           return real_onep (gimple_call_arg (c, 0));
    2663              :         default:
    2664              :           return false;
    2665              :         }
    2666              :     }
    2667              : 
    2668              :    return false;
    2669              : }
    2670              : 
    2671              : /* Try to expand the pattern x * copysign (1, y) into xorsign (x, y).
    2672              :    This only happens when the xorsign optab is defined, if the
    2673              :    pattern is not a xorsign pattern or if expansion fails FALSE is
    2674              :    returned, otherwise TRUE is returned.  */
    2675              : static bool
    2676       745175 : convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
    2677              : {
    2678       745175 :   tree treeop0, treeop1, lhs, type;
    2679       745175 :   location_t loc = gimple_location (stmt);
    2680       745175 :   lhs = gimple_assign_lhs (stmt);
    2681       745175 :   treeop0 = gimple_assign_rhs1 (stmt);
    2682       745175 :   treeop1 = gimple_assign_rhs2 (stmt);
    2683       745175 :   type = TREE_TYPE (lhs);
    2684       745175 :   machine_mode mode = TYPE_MODE (type);
    2685              : 
    2686       745175 :   if (HONOR_SNANS (type))
    2687              :     return false;
    2688              : 
    2689       744772 :   if (TREE_CODE (treeop0) == SSA_NAME && TREE_CODE (treeop1) == SSA_NAME)
    2690              :     {
    2691       238366 :       gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
    2692       238366 :       if (!has_single_use (treeop0) || !is_copysign_call_with_1 (call0))
    2693              :         {
    2694       238340 :           call0 = SSA_NAME_DEF_STMT (treeop1);
    2695       238340 :           if (!has_single_use (treeop1) || !is_copysign_call_with_1 (call0))
    2696              :             return false;
    2697              : 
    2698              :           treeop1 = treeop0;
    2699              :         }
    2700           43 :         if (optab_handler (xorsign_optab, mode) == CODE_FOR_nothing)
    2701              :           return false;
    2702              : 
    2703           43 :         gcall *c = as_a<gcall*> (call0);
    2704           43 :         treeop0 = gimple_call_arg (c, 1);
    2705              : 
    2706           43 :         gcall *call_stmt
    2707           43 :           = gimple_build_call_internal (IFN_XORSIGN, 2, treeop1, treeop0);
    2708           43 :         gimple_set_lhs (call_stmt, lhs);
    2709           43 :         gimple_set_location (call_stmt, loc);
    2710           43 :         gsi_replace (gsi, call_stmt, true);
    2711           43 :         return true;
    2712              :     }
    2713              : 
    2714              :   return false;
    2715              : }
    2716              : 
    2717              : /* Process a single gimple statement STMT, which has a MULT_EXPR as
    2718              :    its rhs, and try to convert it into a WIDEN_MULT_EXPR.  The return
    2719              :    value is true iff we converted the statement.  */
    2720              : 
    2721              : static bool
    2722       754025 : convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
    2723              : {
    2724       754025 :   tree lhs, rhs1, rhs2, type, type1, type2;
    2725       754025 :   enum insn_code handler;
    2726       754025 :   scalar_int_mode to_mode, from_mode, actual_mode;
    2727       754025 :   optab op;
    2728       754025 :   int actual_precision;
    2729       754025 :   location_t loc = gimple_location (stmt);
    2730       754025 :   bool from_unsigned1, from_unsigned2;
    2731              : 
    2732       754025 :   lhs = gimple_assign_lhs (stmt);
    2733       754025 :   type = TREE_TYPE (lhs);
    2734       754025 :   if (TREE_CODE (type) != INTEGER_TYPE)
    2735              :     return false;
    2736              : 
    2737       616461 :   if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))
    2738              :     return false;
    2739              : 
    2740              :   /* if any one of rhs1 and rhs2 is subject to abnormal coalescing,
    2741              :      avoid the transform. */
    2742       153833 :   if ((TREE_CODE (rhs1) == SSA_NAME
    2743       153833 :        && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
    2744       307665 :       || (TREE_CODE (rhs2) == SSA_NAME
    2745        22524 :           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)))
    2746              :     return false;
    2747              : 
    2748       153832 :   to_mode = SCALAR_INT_TYPE_MODE (type);
    2749       153832 :   from_mode = SCALAR_INT_TYPE_MODE (type1);
    2750       153832 :   if (to_mode == from_mode)
    2751              :     return false;
    2752              : 
    2753       153828 :   from_unsigned1 = TYPE_UNSIGNED (type1);
    2754       153828 :   from_unsigned2 = TYPE_UNSIGNED (type2);
    2755              : 
    2756       153828 :   if (from_unsigned1 && from_unsigned2)
    2757              :     op = umul_widen_optab;
    2758        60696 :   else if (!from_unsigned1 && !from_unsigned2)
    2759              :     op = smul_widen_optab;
    2760              :   else
    2761         1866 :     op = usmul_widen_optab;
    2762              : 
    2763       153828 :   handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
    2764              :                                                   &actual_mode);
    2765              : 
    2766       153828 :   if (handler == CODE_FOR_nothing)
    2767              :     {
    2768       144978 :       if (op != smul_widen_optab)
    2769              :         {
    2770              :           /* We can use a signed multiply with unsigned types as long as
    2771              :              there is a wider mode to use, or it is the smaller of the two
    2772              :              types that is unsigned.  Note that type1 >= type2, always.  */
    2773        87645 :           if ((TYPE_UNSIGNED (type1)
    2774        85971 :                && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
    2775        87645 :               || (TYPE_UNSIGNED (type2)
    2776         1674 :                   && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
    2777              :             {
    2778        87645 :               if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
    2779       175290 :                   || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
    2780              :                 return false;
    2781              :             }
    2782              : 
    2783            0 :           op = smul_widen_optab;
    2784            0 :           handler = find_widening_optab_handler_and_mode (op, to_mode,
    2785              :                                                           from_mode,
    2786              :                                                           &actual_mode);
    2787              : 
    2788            0 :           if (handler == CODE_FOR_nothing)
    2789              :             return false;
    2790              : 
    2791              :           from_unsigned1 = from_unsigned2 = false;
    2792              :         }
    2793              :       else
    2794              :         {
    2795              :           /* Expand can synthesize smul_widen_optab if the target
    2796              :              supports umul_widen_optab.  */
    2797        57333 :           op = umul_widen_optab;
    2798        57333 :           handler = find_widening_optab_handler_and_mode (op, to_mode,
    2799              :                                                           from_mode,
    2800              :                                                           &actual_mode);
    2801        57333 :           if (handler == CODE_FOR_nothing)
    2802              :             return false;
    2803              :         }
    2804              :     }
    2805              : 
    2806              :   /* Ensure that the inputs to the handler are in the correct precision
    2807              :      for the opcode.  This will be the full mode size.  */
    2808         8850 :   actual_precision = GET_MODE_PRECISION (actual_mode);
    2809         8850 :   if (2 * actual_precision > TYPE_PRECISION (type))
    2810              :     return false;
    2811         8850 :   if (actual_precision != TYPE_PRECISION (type1)
    2812         8850 :       || from_unsigned1 != TYPE_UNSIGNED (type1))
    2813              :     {
    2814            3 :       if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
    2815              :         {
    2816            0 :           if (TREE_CODE (rhs1) == INTEGER_CST)
    2817            0 :             rhs1 = fold_convert (type1, rhs1);
    2818              :           else
    2819            0 :             rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
    2820              :         }
    2821            3 :       type1 = build_nonstandard_integer_type (actual_precision,
    2822              :                                               from_unsigned1);
    2823              :     }
    2824         8850 :   if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
    2825              :     {
    2826         8113 :       if (TREE_CODE (rhs1) == INTEGER_CST)
    2827            0 :         rhs1 = fold_convert (type1, rhs1);
    2828              :       else
    2829         8113 :         rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
    2830              :     }
    2831         8850 :   if (actual_precision != TYPE_PRECISION (type2)
    2832         8850 :       || from_unsigned2 != TYPE_UNSIGNED (type2))
    2833              :     {
    2834            3 :       if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
    2835              :         {
    2836            3 :           if (TREE_CODE (rhs2) == INTEGER_CST)
    2837            3 :             rhs2 = fold_convert (type2, rhs2);
    2838              :           else
    2839            0 :             rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
    2840              :         }
    2841            3 :       type2 = build_nonstandard_integer_type (actual_precision,
    2842              :                                               from_unsigned2);
    2843              :     }
    2844         8850 :   if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
    2845              :     {
    2846         8308 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    2847         1866 :         rhs2 = fold_convert (type2, rhs2);
    2848              :       else
    2849         6442 :         rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
    2850              :     }
    2851              : 
    2852         8850 :   gimple_assign_set_rhs1 (stmt, rhs1);
    2853         8850 :   gimple_assign_set_rhs2 (stmt, rhs2);
    2854         8850 :   gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
    2855         8850 :   update_stmt (stmt);
    2856         8850 :   widen_mul_stats.widen_mults_inserted++;
    2857         8850 :   return true;
    2858              : }
    2859              : 
    2860              : /* Process a single gimple statement STMT, which is found at the
    2861              :    iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
    2862              :    rhs (given by CODE), and try to convert it into a
    2863              :    WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR.  The return value
    2864              :    is true iff we converted the statement.  */
    2865              : 
    2866              : static bool
    2867      2621896 : convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
    2868              :                             enum tree_code code)
    2869              : {
    2870      2621896 :   gimple *rhs1_stmt = NULL, *rhs2_stmt = NULL;
    2871      2621896 :   gimple *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
    2872      2621896 :   tree type, type1, type2, optype;
    2873      2621896 :   tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
    2874      2621896 :   enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
    2875      2621896 :   optab this_optab;
    2876      2621896 :   enum tree_code wmult_code;
    2877      2621896 :   enum insn_code handler;
    2878      2621896 :   scalar_mode to_mode, from_mode, actual_mode;
    2879      2621896 :   location_t loc = gimple_location (stmt);
    2880      2621896 :   int actual_precision;
    2881      2621896 :   bool from_unsigned1, from_unsigned2;
    2882              : 
    2883      2621896 :   lhs = gimple_assign_lhs (stmt);
    2884      2621896 :   type = TREE_TYPE (lhs);
    2885      2621896 :   if ((TREE_CODE (type) != INTEGER_TYPE
    2886       402563 :        && TREE_CODE (type) != FIXED_POINT_TYPE)
    2887      2621896 :       || !type_has_mode_precision_p (type))
    2888              :     return false;
    2889              : 
    2890      2216664 :   if (code == MINUS_EXPR)
    2891              :     wmult_code = WIDEN_MULT_MINUS_EXPR;
    2892              :   else
    2893      1967166 :     wmult_code = WIDEN_MULT_PLUS_EXPR;
    2894              : 
    2895      2216664 :   rhs1 = gimple_assign_rhs1 (stmt);
    2896      2216664 :   rhs2 = gimple_assign_rhs2 (stmt);
    2897              : 
    2898      2216664 :   if (TREE_CODE (rhs1) == SSA_NAME)
    2899              :     {
    2900      2185284 :       rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
    2901      2185284 :       if (is_gimple_assign (rhs1_stmt))
    2902      1292090 :         rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
    2903              :     }
    2904              : 
    2905      2216664 :   if (TREE_CODE (rhs2) == SSA_NAME)
    2906              :     {
    2907       801549 :       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
    2908       801549 :       if (is_gimple_assign (rhs2_stmt))
    2909       618258 :         rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
    2910              :     }
    2911              : 
    2912              :   /* Allow for one conversion statement between the multiply
    2913              :      and addition/subtraction statement.  If there are more than
    2914              :      one conversions then we assume they would invalidate this
    2915              :      transformation.  If that's not the case then they should have
    2916              :      been folded before now.  */
    2917      2216664 :   if (CONVERT_EXPR_CODE_P (rhs1_code))
    2918              :     {
    2919       419075 :       conv1_stmt = rhs1_stmt;
    2920       419075 :       rhs1 = gimple_assign_rhs1 (rhs1_stmt);
    2921       419075 :       if (TREE_CODE (rhs1) == SSA_NAME)
    2922              :         {
    2923       349768 :           rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
    2924       349768 :           if (is_gimple_assign (rhs1_stmt))
    2925       204683 :             rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
    2926              :         }
    2927              :       else
    2928              :         return false;
    2929              :     }
    2930      2147357 :   if (CONVERT_EXPR_CODE_P (rhs2_code))
    2931              :     {
    2932       196925 :       conv2_stmt = rhs2_stmt;
    2933       196925 :       rhs2 = gimple_assign_rhs1 (rhs2_stmt);
    2934       196925 :       if (TREE_CODE (rhs2) == SSA_NAME)
    2935              :         {
    2936       187244 :           rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
    2937       187244 :           if (is_gimple_assign (rhs2_stmt))
    2938       124795 :             rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
    2939              :         }
    2940              :       else
    2941              :         return false;
    2942              :     }
    2943              : 
    2944              :   /* If code is WIDEN_MULT_EXPR then it would seem unnecessary to call
    2945              :      is_widening_mult_p, but we still need the rhs returns.
    2946              : 
    2947              :      It might also appear that it would be sufficient to use the existing
    2948              :      operands of the widening multiply, but that would limit the choice of
    2949              :      multiply-and-accumulate instructions.
    2950              : 
    2951              :      If the widened-multiplication result has more than one uses, it is
    2952              :      probably wiser not to do the conversion.  Also restrict this operation
    2953              :      to single basic block to avoid moving the multiply to a different block
    2954              :      with a higher execution frequency.  */
    2955      2137676 :   if (code == PLUS_EXPR
    2956      1893363 :       && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
    2957              :     {
    2958       144720 :       if (!has_single_use (rhs1)
    2959        79131 :           || (conv1_stmt
    2960         5166 :               && !has_single_use (gimple_assign_lhs (conv1_stmt)))
    2961        76418 :           || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
    2962       211882 :           || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
    2963              :                                   &type2, &mult_rhs2))
    2964              :         return false;
    2965              :       add_rhs = rhs2;
    2966              :       conv_stmt = conv1_stmt;
    2967              :     }
    2968      1992956 :   else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
    2969              :     {
    2970       129377 :       if (!has_single_use (rhs2)
    2971        79963 :           || (conv2_stmt
    2972         9148 :               && !has_single_use (gimple_assign_lhs (conv2_stmt)))
    2973        78815 :           || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
    2974       200485 :           || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
    2975              :                                   &type2, &mult_rhs2))
    2976              :         return false;
    2977              :       add_rhs = rhs1;
    2978              :       conv_stmt = conv2_stmt;
    2979              :     }
    2980              :   else
    2981              :     return false;
    2982              : 
    2983        31993 :   to_mode = SCALAR_TYPE_MODE (type);
    2984        31993 :   from_mode = SCALAR_TYPE_MODE (type1);
    2985        31993 :   if (to_mode == from_mode)
    2986              :     return false;
    2987              : 
    2988              :   /* For fixed point types, the mode classes could be different
    2989              :      so reject that case. */
    2990        31992 :   if (GET_MODE_CLASS (from_mode) != GET_MODE_CLASS (to_mode))
    2991              :     return false;
    2992              : 
    2993        31992 :   from_unsigned1 = TYPE_UNSIGNED (type1);
    2994        31992 :   from_unsigned2 = TYPE_UNSIGNED (type2);
    2995        31992 :   optype = type1;
    2996              : 
    2997              :   /* There's no such thing as a mixed sign madd yet, so use a wider mode.  */
    2998        31992 :   if (from_unsigned1 != from_unsigned2)
    2999              :     {
    3000          894 :       if (!INTEGRAL_TYPE_P (type))
    3001              :         return false;
    3002              :       /* We can use a signed multiply with unsigned types as long as
    3003              :          there is a wider mode to use, or it is the smaller of the two
    3004              :          types that is unsigned.  Note that type1 >= type2, always.  */
    3005          894 :       if ((from_unsigned1
    3006           54 :            && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
    3007          894 :           || (from_unsigned2
    3008          840 :               && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
    3009              :         {
    3010          894 :           if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
    3011         1788 :               || GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
    3012              :             return false;
    3013              :         }
    3014              : 
    3015           18 :       from_unsigned1 = from_unsigned2 = false;
    3016           18 :       optype = build_nonstandard_integer_type (GET_MODE_PRECISION (from_mode),
    3017              :                                                false);
    3018              :     }
    3019              : 
    3020              :   /* If there was a conversion between the multiply and addition
    3021              :      then we need to make sure it fits a multiply-and-accumulate.
    3022              :      The should be a single mode change which does not change the
    3023              :      value.  */
    3024        31116 :   if (conv_stmt)
    3025              :     {
    3026              :       /* We use the original, unmodified data types for this.  */
    3027          706 :       tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
    3028          706 :       tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
    3029          706 :       int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
    3030          706 :       bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
    3031              : 
    3032          706 :       if (TYPE_PRECISION (from_type) > TYPE_PRECISION (to_type))
    3033              :         {
    3034              :           /* Conversion is a truncate.  */
    3035            0 :           if (TYPE_PRECISION (to_type) < data_size)
    3036              :             return false;
    3037              :         }
    3038          706 :       else if (TYPE_PRECISION (from_type) < TYPE_PRECISION (to_type))
    3039              :         {
    3040              :           /* Conversion is an extend.  Check it's the right sort.  */
    3041          367 :           if (TYPE_UNSIGNED (from_type) != is_unsigned
    3042          367 :               && !(is_unsigned && TYPE_PRECISION (from_type) > data_size))
    3043              :             return false;
    3044              :         }
    3045              :       /* else convert is a no-op for our purposes.  */
    3046              :     }
    3047              : 
    3048              :   /* Verify that the machine can perform a widening multiply
    3049              :      accumulate in this mode/signedness combination, otherwise
    3050              :      this transformation is likely to pessimize code.  */
    3051        30824 :   this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
    3052        30824 :   handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
    3053              :                                                   from_mode, &actual_mode);
    3054              : 
    3055        30824 :   if (handler == CODE_FOR_nothing)
    3056              :     return false;
    3057              : 
    3058              :   /* Ensure that the inputs to the handler are in the correct precision
    3059              :      for the opcode.  This will be the full mode size.  */
    3060            0 :   actual_precision = GET_MODE_PRECISION (actual_mode);
    3061            0 :   if (actual_precision != TYPE_PRECISION (type1)
    3062            0 :       || from_unsigned1 != TYPE_UNSIGNED (type1))
    3063              :     {
    3064            0 :       if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
    3065              :         {
    3066            0 :           if (TREE_CODE (mult_rhs1) == INTEGER_CST)
    3067            0 :             mult_rhs1 = fold_convert (type1, mult_rhs1);
    3068              :           else
    3069            0 :             mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
    3070              :         }
    3071            0 :       type1 = build_nonstandard_integer_type (actual_precision,
    3072              :                                               from_unsigned1);
    3073              :     }
    3074            0 :   if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
    3075              :     {
    3076            0 :       if (TREE_CODE (mult_rhs1) == INTEGER_CST)
    3077            0 :         mult_rhs1 = fold_convert (type1, mult_rhs1);
    3078              :       else
    3079            0 :         mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
    3080              :     }
    3081            0 :   if (actual_precision != TYPE_PRECISION (type2)
    3082            0 :       || from_unsigned2 != TYPE_UNSIGNED (type2))
    3083              :     {
    3084            0 :       if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
    3085              :         {
    3086            0 :           if (TREE_CODE (mult_rhs2) == INTEGER_CST)
    3087            0 :             mult_rhs2 = fold_convert (type2, mult_rhs2);
    3088              :           else
    3089            0 :             mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
    3090              :         }
    3091            0 :       type2 = build_nonstandard_integer_type (actual_precision,
    3092              :                                               from_unsigned2);
    3093              :     }
    3094            0 :   if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
    3095              :     {
    3096            0 :       if (TREE_CODE (mult_rhs2) == INTEGER_CST)
    3097            0 :         mult_rhs2 = fold_convert (type2, mult_rhs2);
    3098              :       else
    3099            0 :         mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
    3100              :     }
    3101              : 
    3102            0 :   if (!useless_type_conversion_p (type, TREE_TYPE (add_rhs)))
    3103            0 :     add_rhs = build_and_insert_cast (gsi, loc, type, add_rhs);
    3104              : 
    3105            0 :   gimple_assign_set_rhs_with_ops (gsi, wmult_code, mult_rhs1, mult_rhs2,
    3106              :                                   add_rhs);
    3107            0 :   update_stmt (gsi_stmt (*gsi));
    3108            0 :   widen_mul_stats.maccs_inserted++;
    3109            0 :   return true;
    3110              : }
    3111              : 
    3112              : /* Given a result MUL_RESULT which is a result of a multiplication of OP1 and
    3113              :    OP2 and which we know is used in statements that can be, together with the
    3114              :    multiplication, converted to FMAs, perform the transformation.  */
    3115              : 
    3116              : static void
    3117        17541 : convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
    3118              : {
    3119        17541 :   gimple *use_stmt;
    3120        17541 :   imm_use_iterator imm_iter;
    3121        17541 :   gcall *fma_stmt;
    3122              : 
    3123        35141 :   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result)
    3124              :     {
    3125        17600 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    3126        17600 :       tree addop, mulop1 = op1, result = mul_result;
    3127        17600 :       bool negate_p = false;
    3128        17600 :       gimple_seq seq = NULL;
    3129              : 
    3130        17600 :       if (is_gimple_debug (use_stmt))
    3131            0 :         continue;
    3132              : 
    3133              :       /* If the use is a type convert, look further into it if the operations
    3134              :          are the same under two's complement.  */
    3135        17600 :       tree lhs_type;
    3136        17600 :       if (gimple_assign_cast_p (use_stmt)
    3137            0 :           && (lhs_type = TREE_TYPE (gimple_get_lhs (use_stmt)))
    3138        17600 :           && tree_nop_conversion_p (lhs_type, TREE_TYPE (op1)))
    3139              :         {
    3140            0 :           tree cast_lhs = gimple_get_lhs (use_stmt);
    3141            0 :           gimple *tmp_use;
    3142            0 :           use_operand_p tmp_use_p;
    3143            0 :           if (single_imm_use (cast_lhs, &tmp_use_p, &tmp_use))
    3144              :             {
    3145            0 :               release_defs (use_stmt);
    3146            0 :               use_stmt = tmp_use;
    3147            0 :               result = cast_lhs;
    3148            0 :               gsi_remove (&gsi, true);
    3149            0 :               gsi = gsi_for_stmt (use_stmt);
    3150              :             }
    3151              :         }
    3152              : 
    3153        17600 :       if (is_gimple_assign (use_stmt)
    3154        17600 :           && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
    3155              :         {
    3156          700 :           result = gimple_assign_lhs (use_stmt);
    3157          700 :           use_operand_p use_p;
    3158          700 :           gimple *neguse_stmt;
    3159          700 :           single_imm_use (gimple_assign_lhs (use_stmt), &use_p, &neguse_stmt);
    3160          700 :           gsi_remove (&gsi, true);
    3161          700 :           release_defs (use_stmt);
    3162              : 
    3163          700 :           use_stmt = neguse_stmt;
    3164          700 :           gsi = gsi_for_stmt (use_stmt);
    3165          700 :           negate_p = true;
    3166              :         }
    3167              : 
    3168        17600 :       tree cond, else_value, ops[3], len, bias;
    3169        17600 :       tree_code code;
    3170        17600 :       if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code,
    3171              :                                               ops, &else_value,
    3172              :                                               &len, &bias))
    3173            0 :         gcc_unreachable ();
    3174        17600 :       addop = ops[0] == result ? ops[1] : ops[0];
    3175              : 
    3176        17600 :       if (code == MINUS_EXPR)
    3177              :         {
    3178         5839 :           if (ops[0] == result)
    3179              :             /* a * b - c -> a * b + (-c)  */
    3180         2916 :             addop = gimple_build (&seq, NEGATE_EXPR, TREE_TYPE (addop), addop);
    3181              :           else
    3182              :             /* a - b * c -> (-b) * c + a */
    3183         2923 :             negate_p = !negate_p;
    3184              :         }
    3185              : 
    3186        17600 :       if (negate_p)
    3187         3623 :         mulop1 = gimple_build (&seq, NEGATE_EXPR, TREE_TYPE (mulop1), mulop1);
    3188              : 
    3189        17600 :       if (seq)
    3190         5834 :         gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    3191              : 
    3192              :       /* Ensure all the operands are of the same type.  Use the type of the
    3193              :          addend as that's the statement being replaced.  */
    3194        17600 :       op2 = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3195        17600 :                             UNKNOWN_LOCATION, TREE_TYPE (addop), op2);
    3196        17600 :       mulop1 = gimple_convert (&gsi, true, GSI_SAME_STMT,
    3197        17600 :                                UNKNOWN_LOCATION, TREE_TYPE (addop), mulop1);
    3198              : 
    3199        17600 :       if (len)
    3200            0 :         fma_stmt
    3201            0 :           = gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2,
    3202              :                                         addop, else_value, len, bias);
    3203        17600 :       else if (cond)
    3204           94 :         fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
    3205              :                                                op2, addop, else_value);
    3206              :       else
    3207        17506 :         fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
    3208        17600 :       gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
    3209        17600 :       gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
    3210              :                                                                    use_stmt));
    3211        17600 :       gsi_replace (&gsi, fma_stmt, true);
    3212              :       /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
    3213              :          regardless of where the negation occurs.  */
    3214        17600 :       gimple *orig_stmt = gsi_stmt (gsi);
    3215        17600 :       if (fold_stmt (&gsi, follow_all_ssa_edges))
    3216              :         {
    3217         5883 :           if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
    3218            0 :             gcc_unreachable ();
    3219         5883 :           update_stmt (gsi_stmt (gsi));
    3220              :         }
    3221              : 
    3222        17600 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3223              :         {
    3224            3 :           fprintf (dump_file, "Generated FMA ");
    3225            3 :           print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
    3226            3 :           fprintf (dump_file, "\n");
    3227              :         }
    3228              : 
    3229              :       /* If the FMA result is negated in a single use, fold the negation
    3230              :          too.  */
    3231        17600 :       orig_stmt = gsi_stmt (gsi);
    3232        17600 :       use_operand_p use_p;
    3233        17600 :       gimple *neg_stmt;
    3234        17600 :       if (is_gimple_call (orig_stmt)
    3235        17600 :           && gimple_call_internal_p (orig_stmt)
    3236        17600 :           && gimple_call_lhs (orig_stmt)
    3237        17600 :           && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME
    3238        17600 :           && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt)
    3239        12552 :           && is_gimple_assign (neg_stmt)
    3240         9888 :           && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR
    3241        18953 :           && !stmt_could_throw_p (cfun, neg_stmt))
    3242              :         {
    3243         1353 :           gsi = gsi_for_stmt (neg_stmt);
    3244         1353 :           if (fold_stmt (&gsi, follow_all_ssa_edges))
    3245              :             {
    3246         1353 :               if (maybe_clean_or_replace_eh_stmt (neg_stmt, gsi_stmt (gsi)))
    3247            0 :                 gcc_unreachable ();
    3248         1353 :               update_stmt (gsi_stmt (gsi));
    3249         1353 :               if (dump_file && (dump_flags & TDF_DETAILS))
    3250              :                 {
    3251            0 :                   fprintf (dump_file, "Folded FMA negation ");
    3252            0 :                   print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
    3253            0 :                   fprintf (dump_file, "\n");
    3254              :                 }
    3255              :             }
    3256              :         }
    3257              : 
    3258        17600 :       widen_mul_stats.fmas_inserted++;
    3259        17541 :     }
    3260        17541 : }
    3261              : 
    3262              : /* Data necessary to perform the actual transformation from a multiplication
    3263              :    and an addition to an FMA after decision is taken it should be done and to
    3264              :    then delete the multiplication statement from the function IL.  */
    3265              : 
    3266              : struct fma_transformation_info
    3267              : {
    3268              :   gimple *mul_stmt;
    3269              :   tree mul_result;
    3270              :   tree op1;
    3271              :   tree op2;
    3272              : };
    3273              : 
    3274              : /* Structure containing the current state of FMA deferring, i.e. whether we are
    3275              :    deferring, whether to continue deferring, and all data necessary to come
    3276              :    back and perform all deferred transformations.  */
    3277              : 
    3278     10458165 : class fma_deferring_state
    3279              : {
    3280              : public:
    3281              :   /* Class constructor.  Pass true as PERFORM_DEFERRING in order to actually
    3282              :      do any deferring.  */
    3283              : 
    3284     10458165 :   fma_deferring_state (bool perform_deferring)
    3285     10458165 :     : m_candidates (), m_mul_result_set (), m_initial_phi (NULL),
    3286     10458165 :       m_last_result (NULL_TREE), m_deferring_p (perform_deferring) {}
    3287              : 
    3288              :   /* List of FMA candidates for which we the transformation has been determined
    3289              :      possible but we at this point in BB analysis we do not consider them
    3290              :      beneficial.  */
    3291              :   auto_vec<fma_transformation_info, 8> m_candidates;
    3292              : 
    3293              :   /* Set of results of multiplication that are part of an already deferred FMA
    3294              :      candidates.  */
    3295              :   hash_set<tree> m_mul_result_set;
    3296              : 
    3297              :   /* The PHI that supposedly feeds back result of a FMA to another over loop
    3298              :      boundary.  */
    3299              :   gphi *m_initial_phi;
    3300              : 
    3301              :   /* Result of the last produced FMA candidate or NULL if there has not been
    3302              :      one.  */
    3303              :   tree m_last_result;
    3304              : 
    3305              :   /* If true, deferring might still be profitable.  If false, transform all
    3306              :      candidates and no longer defer.  */
    3307              :   bool m_deferring_p;
    3308              : };
    3309              : 
    3310              : /* Transform all deferred FMA candidates and mark STATE as no longer
    3311              :    deferring.  */
    3312              : 
    3313              : static void
    3314      3735398 : cancel_fma_deferring (fma_deferring_state *state)
    3315              : {
    3316      3735398 :   if (!state->m_deferring_p)
    3317              :     return;
    3318              : 
    3319      2698546 :   for (unsigned i = 0; i < state->m_candidates.length (); i++)
    3320              :     {
    3321          940 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3322            0 :         fprintf (dump_file, "Generating deferred FMA\n");
    3323              : 
    3324          940 :       const fma_transformation_info &fti = state->m_candidates[i];
    3325          940 :       convert_mult_to_fma_1 (fti.mul_result, fti.op1, fti.op2);
    3326              : 
    3327          940 :       gimple_stmt_iterator gsi = gsi_for_stmt (fti.mul_stmt);
    3328          940 :       gsi_remove (&gsi, true);
    3329          940 :       release_defs (fti.mul_stmt);
    3330              :     }
    3331      2697606 :   state->m_deferring_p = false;
    3332              : }
    3333              : 
    3334              : /* If OP is an SSA name defined by a PHI node, return the PHI statement.
    3335              :    Otherwise return NULL.  */
    3336              : 
    3337              : static gphi *
    3338         5266 : result_of_phi (tree op)
    3339              : {
    3340            0 :   if (TREE_CODE (op) != SSA_NAME)
    3341              :     return NULL;
    3342              : 
    3343         5141 :   return dyn_cast <gphi *> (SSA_NAME_DEF_STMT (op));
    3344              : }
    3345              : 
    3346              : /* After processing statements of a BB and recording STATE, return true if the
    3347              :    initial phi is fed by the last FMA candidate result ore one such result from
    3348              :    previously processed BBs marked in LAST_RESULT_SET.  */
    3349              : 
    3350              : static bool
    3351          361 : last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
    3352              :                                       hash_set<tree> *last_result_set)
    3353              : {
    3354          361 :   ssa_op_iter iter;
    3355          361 :   use_operand_p use;
    3356          889 :   FOR_EACH_PHI_ARG (use, state->m_initial_phi, iter, SSA_OP_USE)
    3357              :     {
    3358          625 :       tree t = USE_FROM_PTR (use);
    3359          625 :       if (t == state->m_last_result
    3360          625 :           || last_result_set->contains (t))
    3361           97 :         return true;
    3362              :     }
    3363              : 
    3364              :   return false;
    3365              : }
    3366              : 
    3367              : /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
    3368              :    with uses in additions and subtractions to form fused multiply-add
    3369              :    operations.  Returns true if successful and MUL_STMT should be removed.
    3370              :    If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
    3371              :    on MUL_COND, otherwise it is unconditional.
    3372              : 
    3373              :    If STATE indicates that we are deferring FMA transformation, that means
    3374              :    that we do not produce FMAs for basic blocks which look like:
    3375              : 
    3376              :     <bb 6>
    3377              :     # accumulator_111 = PHI <0.0(5), accumulator_66(6)>
    3378              :     _65 = _14 * _16;
    3379              :     accumulator_66 = _65 + accumulator_111;
    3380              : 
    3381              :   or its unrolled version, i.e. with several FMA candidates that feed result
    3382              :   of one into the addend of another.  Instead, we add them to a list in STATE
    3383              :   and if we later discover an FMA candidate that is not part of such a chain,
    3384              :   we go back and perform all deferred past candidates.  */
    3385              : 
    3386              : static bool
    3387       745261 : convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
    3388              :                      fma_deferring_state *state, tree mul_cond = NULL_TREE,
    3389              :                      tree mul_len = NULL_TREE, tree mul_bias = NULL_TREE)
    3390              : {
    3391       745261 :   tree mul_result = gimple_get_lhs (mul_stmt);
    3392              :   /* If there isn't a LHS then this can't be an FMA.  There can be no LHS
    3393              :      if the statement was left just for the side-effects.  */
    3394       745261 :   if (!mul_result)
    3395              :     return false;
    3396       745261 :   tree type = TREE_TYPE (mul_result);
    3397       745261 :   gimple *use_stmt, *neguse_stmt;
    3398       745261 :   use_operand_p use_p;
    3399       745261 :   imm_use_iterator imm_iter;
    3400              : 
    3401       647495 :   if (FLOAT_TYPE_P (type)
    3402       771007 :       && flag_fp_contract_mode != FP_CONTRACT_FAST)
    3403              :     return false;
    3404              : 
    3405              :   /* We don't want to do bitfield reduction ops.  */
    3406       740172 :   if (INTEGRAL_TYPE_P (type)
    3407       740172 :       && (!type_has_mode_precision_p (type) || TYPE_OVERFLOW_TRAPS (type)))
    3408              :     return false;
    3409              : 
    3410              :   /* If the target doesn't support it, don't generate it.  We assume that
    3411              :      if fma isn't available then fms, fnma or fnms are not either.  */
    3412       739975 :   optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt));
    3413       739975 :   if (!direct_internal_fn_supported_p (IFN_FMA, type, opt_type))
    3414              :     return false;
    3415              : 
    3416              :   /* If the multiplication has zero uses, it is kept around probably because
    3417              :      of -fnon-call-exceptions.  Don't optimize it away in that case,
    3418              :      it is DCE job.  */
    3419        23040 :   if (has_zero_uses (mul_result))
    3420              :     return false;
    3421              : 
    3422        23040 :   bool check_defer
    3423        23040 :     = (state->m_deferring_p
    3424        23040 :        && maybe_le (tree_to_poly_int64 (TYPE_SIZE (type)),
    3425        23040 :                     param_avoid_fma_max_bits));
    3426        23040 :   bool defer = check_defer;
    3427        23040 :   bool seen_negate_p = false;
    3428              : 
    3429              :   /* There is no numerical difference between fused and unfused integer FMAs,
    3430              :      and the assumption below that FMA is as cheap as addition is unlikely
    3431              :      to be true, especially if the multiplication occurs multiple times on
    3432              :      the same chain.  E.g., for something like:
    3433              : 
    3434              :          (((a * b) + c) >> 1) + (a * b)
    3435              : 
    3436              :      we do not want to duplicate the a * b into two additions, not least
    3437              :      because the result is not a natural FMA chain.  */
    3438        23040 :   if (ANY_INTEGRAL_TYPE_P (type)
    3439        23040 :       && !has_single_use (mul_result))
    3440              :     return false;
    3441              : 
    3442        23040 :   if (!dbg_cnt (form_fma))
    3443              :     return false;
    3444              : 
    3445              :   /* Make sure that the multiplication statement becomes dead after
    3446              :      the transformation, thus that all uses are transformed to FMAs.
    3447              :      This means we assume that an FMA operation has the same cost
    3448              :      as an addition.  */
    3449        41425 :   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
    3450              :     {
    3451        23787 :       tree result = mul_result;
    3452        23787 :       bool negate_p = false;
    3453              : 
    3454        23787 :       use_stmt = USE_STMT (use_p);
    3455              : 
    3456        23787 :       if (is_gimple_debug (use_stmt))
    3457          214 :         continue;
    3458              : 
    3459              :       /* If the use is a type convert, look further into it if the operations
    3460              :          are the same under two's complement.  */
    3461        23573 :       tree lhs_type;
    3462        23573 :       if (gimple_assign_cast_p (use_stmt)
    3463          243 :           && (lhs_type = TREE_TYPE (gimple_get_lhs (use_stmt)))
    3464        23816 :           && tree_nop_conversion_p (lhs_type, TREE_TYPE (op1)))
    3465              :         {
    3466            0 :           tree cast_lhs = gimple_get_lhs (use_stmt);
    3467            0 :           gimple *tmp_use;
    3468            0 :           use_operand_p tmp_use_p;
    3469            0 :           if (single_imm_use (cast_lhs, &tmp_use_p, &tmp_use))
    3470            0 :             use_stmt = tmp_use;
    3471            0 :           result = cast_lhs;
    3472              :         }
    3473              : 
    3474              :       /* For now restrict this operations to single basic blocks.  In theory
    3475              :          we would want to support sinking the multiplication in
    3476              :          m = a*b;
    3477              :          if ()
    3478              :            ma = m + c;
    3479              :          else
    3480              :            d = m;
    3481              :          to form a fma in the then block and sink the multiplication to the
    3482              :          else block.  */
    3483        23573 :       if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
    3484         5402 :         return false;
    3485              : 
    3486              :       /* A negate on the multiplication leads to FNMA.  */
    3487        22705 :       if (is_gimple_assign (use_stmt)
    3488        22705 :           && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
    3489              :         {
    3490          706 :           ssa_op_iter iter;
    3491          706 :           use_operand_p usep;
    3492              : 
    3493              :           /* If (due to earlier missed optimizations) we have two
    3494              :              negates of the same value, treat them as equivalent
    3495              :              to a single negate with multiple uses.  */
    3496          706 :           if (seen_negate_p)
    3497            0 :             return false;
    3498              : 
    3499          706 :           result = gimple_assign_lhs (use_stmt);
    3500              : 
    3501              :           /* Make sure the negate statement becomes dead with this
    3502              :              single transformation.  */
    3503          706 :           if (!single_imm_use (gimple_assign_lhs (use_stmt),
    3504              :                                &use_p, &neguse_stmt))
    3505              :             return false;
    3506              : 
    3507              :           /* Make sure the multiplication isn't also used on that stmt.  */
    3508         2836 :           FOR_EACH_PHI_OR_STMT_USE (usep, neguse_stmt, iter, SSA_OP_USE)
    3509         1424 :             if (USE_FROM_PTR (usep) == mul_result)
    3510              :               return false;
    3511              : 
    3512              :           /* Re-validate.  */
    3513          706 :           use_stmt = neguse_stmt;
    3514          706 :           if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
    3515              :             return false;
    3516              : 
    3517          706 :           negate_p = seen_negate_p = true;
    3518              :         }
    3519              : 
    3520        22705 :       tree cond, else_value, ops[3], len, bias;
    3521        22705 :       tree_code code;
    3522        22705 :       if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
    3523              :                                               &else_value, &len, &bias))
    3524              :         return false;
    3525              : 
    3526              :       /* The multiplication result must be one of the addition operands.  */
    3527        20346 :       if (ops[0] != result && ops[1] != result)
    3528              :         return false;
    3529              : 
    3530        19733 :       switch (code)
    3531              :         {
    3532         5845 :         case MINUS_EXPR:
    3533         5845 :           if (ops[1] == result)
    3534         2923 :             negate_p = !negate_p;
    3535              :           break;
    3536              :         case PLUS_EXPR:
    3537              :           break;
    3538              :         default:
    3539              :           /* FMA can only be formed from PLUS and MINUS.  */
    3540              :           return false;
    3541              :         }
    3542              : 
    3543        18193 :       if (len)
    3544              :         {
    3545              :           /* For COND_LEN_* operations, we may have dummpy mask which is
    3546              :              the all true mask.  Such TREE type may be mul_cond != cond
    3547              :              but we still consider they are equal.  */
    3548            0 :           if (mul_cond && cond != mul_cond
    3549            0 :               && !(integer_truep (mul_cond) && integer_truep (cond)))
    3550              :             return false;
    3551              : 
    3552            0 :           if (else_value == result)
    3553              :             return false;
    3554              : 
    3555            0 :           if (!direct_internal_fn_supported_p (IFN_COND_LEN_FMA, type,
    3556              :                                                opt_type))
    3557              :             return false;
    3558              : 
    3559            0 :           if (mul_len)
    3560              :             {
    3561            0 :               poly_int64 mul_value, value;
    3562            0 :               if (poly_int_tree_p (mul_len, &mul_value)
    3563            0 :                   && poly_int_tree_p (len, &value)
    3564            0 :                   && maybe_ne (mul_value, value))
    3565            0 :                 return false;
    3566            0 :               else if (mul_len != len)
    3567              :                 return false;
    3568              : 
    3569            0 :               if (wi::to_widest (mul_bias) != wi::to_widest (bias))
    3570              :                 return false;
    3571              :             }
    3572              :         }
    3573              :       else
    3574              :         {
    3575        18193 :           if (mul_cond && cond != mul_cond)
    3576              :             return false;
    3577              : 
    3578        18181 :           if (cond)
    3579              :             {
    3580          104 :               if (cond == result || else_value == result)
    3581              :                 return false;
    3582           94 :               if (!direct_internal_fn_supported_p (IFN_COND_FMA, type,
    3583              :                                                    opt_type))
    3584              :                 return false;
    3585              :             }
    3586              :         }
    3587              : 
    3588              :       /* If the subtrahend (OPS[1]) is computed by a MULT_EXPR that
    3589              :          we'll visit later, we might be able to get a more profitable
    3590              :          match with fnma.
    3591              :          OTOH, if we don't, a negate / fma pair has likely lower latency
    3592              :          that a mult / subtract pair.  */
    3593        18171 :       if (code == MINUS_EXPR
    3594         5839 :           && !negate_p
    3595         2216 :           && ops[0] == result
    3596         2216 :           && !direct_internal_fn_supported_p (IFN_FMS, type, opt_type)
    3597            0 :           && direct_internal_fn_supported_p (IFN_FNMA, type, opt_type)
    3598            0 :           && TREE_CODE (ops[1]) == SSA_NAME
    3599        18171 :           && has_single_use (ops[1]))
    3600              :         {
    3601            0 :           gimple *stmt2 = SSA_NAME_DEF_STMT (ops[1]);
    3602            0 :           if (is_gimple_assign (stmt2)
    3603            0 :               && gimple_assign_rhs_code (stmt2) == MULT_EXPR)
    3604              :             return false;
    3605              :         }
    3606              : 
    3607              :       /* We can't handle a * b + a * b.  */
    3608        18171 :       if (ops[0] == ops[1])
    3609              :         return false;
    3610              :       /* If deferring, make sure we are not looking at an instruction that
    3611              :          wouldn't have existed if we were not.  */
    3612        18171 :       if (state->m_deferring_p
    3613        18171 :           && (state->m_mul_result_set.contains (ops[0])
    3614         6461 :               || state->m_mul_result_set.contains (ops[1])))
    3615              :         return false;
    3616              : 
    3617        18171 :       if (check_defer)
    3618              :         {
    3619         6318 :           tree use_lhs = gimple_get_lhs (use_stmt);
    3620         6318 :           if (state->m_last_result)
    3621              :             {
    3622         1052 :               if (ops[1] == state->m_last_result
    3623         1052 :                   || ops[0] == state->m_last_result)
    3624              :                 defer = true;
    3625              :               else
    3626         6318 :                 defer = false;
    3627              :             }
    3628              :           else
    3629              :             {
    3630         5266 :               gcc_checking_assert (!state->m_initial_phi);
    3631         5266 :               gphi *phi;
    3632         5266 :               if (ops[0] == result)
    3633         3339 :                 phi = result_of_phi (ops[1]);
    3634              :               else
    3635              :                 {
    3636         1927 :                   gcc_assert (ops[1] == result);
    3637         1927 :                   phi = result_of_phi (ops[0]);
    3638              :                 }
    3639              : 
    3640              :               if (phi)
    3641              :                 {
    3642          963 :                   state->m_initial_phi = phi;
    3643          963 :                   defer = true;
    3644              :                 }
    3645              :               else
    3646              :                 defer = false;
    3647              :             }
    3648              : 
    3649         6318 :           state->m_last_result = use_lhs;
    3650         6318 :           check_defer = false;
    3651              :         }
    3652              :       else
    3653              :         defer = false;
    3654              : 
    3655              :       /* While it is possible to validate whether or not the exact form that
    3656              :          we've recognized is available in the backend, the assumption is that
    3657              :          if the deferring logic above did not trigger, the transformation is
    3658              :          never a loss.  For instance, suppose the target only has the plain FMA
    3659              :          pattern available.  Consider a*b-c -> fma(a,b,-c): we've exchanged
    3660              :          MUL+SUB for FMA+NEG, which is still two operations.  Consider
    3661              :          -(a*b)-c -> fma(-a,b,-c): we still have 3 operations, but in the FMA
    3662              :          form the two NEGs are independent and could be run in parallel.  */
    3663         5402 :     }
    3664              : 
    3665        17638 :   if (defer)
    3666              :     {
    3667         1037 :       fma_transformation_info fti;
    3668         1037 :       fti.mul_stmt = mul_stmt;
    3669         1037 :       fti.mul_result = mul_result;
    3670         1037 :       fti.op1 = op1;
    3671         1037 :       fti.op2 = op2;
    3672         1037 :       state->m_candidates.safe_push (fti);
    3673         1037 :       state->m_mul_result_set.add (mul_result);
    3674              : 
    3675         1037 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3676              :         {
    3677            0 :           fprintf (dump_file, "Deferred generating FMA for multiplication ");
    3678            0 :           print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE);
    3679            0 :           fprintf (dump_file, "\n");
    3680              :         }
    3681              : 
    3682         1037 :       return false;
    3683              :     }
    3684              :   else
    3685              :     {
    3686        16601 :       if (state->m_deferring_p)
    3687         4922 :         cancel_fma_deferring (state);
    3688        16601 :       convert_mult_to_fma_1 (mul_result, op1, op2);
    3689        16601 :       return true;
    3690              :     }
    3691              : }
    3692              : 
    3693              : 
    3694              : /* Helper function of match_arith_overflow.  For MUL_OVERFLOW, if we have
    3695              :    a check for non-zero like:
    3696              :    _1 = x_4(D) * y_5(D);
    3697              :    *res_7(D) = _1;
    3698              :    if (x_4(D) != 0)
    3699              :      goto <bb 3>; [50.00%]
    3700              :    else
    3701              :      goto <bb 4>; [50.00%]
    3702              : 
    3703              :    <bb 3> [local count: 536870913]:
    3704              :    _2 = _1 / x_4(D);
    3705              :    _9 = _2 != y_5(D);
    3706              :    _10 = (int) _9;
    3707              : 
    3708              :    <bb 4> [local count: 1073741824]:
    3709              :    # iftmp.0_3 = PHI <_10(3), 0(2)>
    3710              :    then in addition to using .MUL_OVERFLOW (x_4(D), y_5(D)) we can also
    3711              :    optimize the x_4(D) != 0 condition to 1.  */
    3712              : 
    3713              : static void
    3714          173 : maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
    3715              :                                gimple *div_stmt, bool *cfg_changed)
    3716              : {
    3717          173 :   basic_block bb = gimple_bb (cond_stmt);
    3718          346 :   if (gimple_bb (div_stmt) != bb || !single_pred_p (bb))
    3719           63 :     return;
    3720          173 :   edge pred_edge = single_pred_edge (bb);
    3721          173 :   basic_block pred_bb = pred_edge->src;
    3722          173 :   if (EDGE_COUNT (pred_bb->succs) != 2)
    3723              :     return;
    3724          130 :   edge other_edge = EDGE_SUCC (pred_bb, EDGE_SUCC (pred_bb, 0) == pred_edge);
    3725          130 :   edge other_succ_edge = NULL;
    3726          130 :   if (gimple_code (cond_stmt) == GIMPLE_COND)
    3727              :     {
    3728           48 :       if (EDGE_COUNT (bb->succs) != 2)
    3729              :         return;
    3730           48 :       other_succ_edge = EDGE_SUCC (bb, 0);
    3731           48 :       if (gimple_cond_code (cond_stmt) == NE_EXPR)
    3732              :         {
    3733           24 :           if (other_succ_edge->flags & EDGE_TRUE_VALUE)
    3734           24 :             other_succ_edge = EDGE_SUCC (bb, 1);
    3735              :         }
    3736              :       else if (other_succ_edge->flags & EDGE_FALSE_VALUE)
    3737           48 :         other_succ_edge = EDGE_SUCC (bb, 0);
    3738           48 :       if (other_edge->dest != other_succ_edge->dest)
    3739              :         return;
    3740              :     }
    3741          140 :   else if (!single_succ_p (bb) || other_edge->dest != single_succ (bb))
    3742              :     return;
    3743          311 :   gcond *zero_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (pred_bb));
    3744          124 :   if (zero_cond == NULL
    3745          124 :       || (gimple_cond_code (zero_cond)
    3746          124 :           != ((pred_edge->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR))
    3747          124 :       || !integer_zerop (gimple_cond_rhs (zero_cond)))
    3748              :     return;
    3749          124 :   tree zero_cond_lhs = gimple_cond_lhs (zero_cond);
    3750          124 :   if (TREE_CODE (zero_cond_lhs) != SSA_NAME)
    3751              :     return;
    3752          124 :   if (gimple_assign_rhs2 (div_stmt) != zero_cond_lhs)
    3753              :     {
    3754              :       /* Allow the divisor to be result of a same precision cast
    3755              :          from zero_cond_lhs.  */
    3756           60 :       tree rhs2 = gimple_assign_rhs2 (div_stmt);
    3757           60 :       if (TREE_CODE (rhs2) != SSA_NAME)
    3758              :         return;
    3759           60 :       gimple *g = SSA_NAME_DEF_STMT (rhs2);
    3760           60 :       if (!gimple_assign_cast_p (g)
    3761           53 :           || gimple_assign_rhs1 (g) != gimple_cond_lhs (zero_cond)
    3762           53 :           || !INTEGRAL_TYPE_P (TREE_TYPE (zero_cond_lhs))
    3763          113 :           || (TYPE_PRECISION (TREE_TYPE (zero_cond_lhs))
    3764           53 :               != TYPE_PRECISION (TREE_TYPE (rhs2))))
    3765              :         return;
    3766              :     }
    3767          117 :   gimple_stmt_iterator gsi = gsi_after_labels (bb);
    3768          117 :   mul_stmts.safe_push (div_stmt);
    3769          117 :   if (is_gimple_debug (gsi_stmt (gsi)))
    3770            0 :     gsi_next_nondebug (&gsi);
    3771          117 :   unsigned cast_count = 0;
    3772          667 :   while (gsi_stmt (gsi) != cond_stmt)
    3773              :     {
    3774              :       /* If original mul_stmt has a single use, allow it in the same bb,
    3775              :          we are looking then just at __builtin_mul_overflow_p.
    3776              :          Though, in that case the original mul_stmt will be replaced
    3777              :          by .MUL_OVERFLOW, REALPART_EXPR and IMAGPART_EXPR stmts.  */
    3778              :       gimple *mul_stmt;
    3779              :       unsigned int i;
    3780         2443 :       bool ok = false;
    3781         2443 :       FOR_EACH_VEC_ELT (mul_stmts, i, mul_stmt)
    3782              :         {
    3783         2296 :           if (gsi_stmt (gsi) == mul_stmt)
    3784              :             {
    3785              :               ok = true;
    3786              :               break;
    3787              :             }
    3788              :         }
    3789          550 :       if (!ok && gimple_assign_cast_p (gsi_stmt (gsi)) && ++cast_count < 4)
    3790              :         ok = true;
    3791          403 :       if (!ok)
    3792           63 :         return;
    3793          550 :       gsi_next_nondebug (&gsi);
    3794              :     }
    3795          117 :   if (gimple_code (cond_stmt) == GIMPLE_COND)
    3796              :     {
    3797           47 :       basic_block succ_bb = other_edge->dest;
    3798           75 :       for (gphi_iterator gpi = gsi_start_phis (succ_bb); !gsi_end_p (gpi);
    3799           28 :            gsi_next (&gpi))
    3800              :         {
    3801           35 :           gphi *phi = gpi.phi ();
    3802           35 :           tree v1 = gimple_phi_arg_def (phi, other_edge->dest_idx);
    3803           35 :           tree v2 = gimple_phi_arg_def (phi, other_succ_edge->dest_idx);
    3804           35 :           if (!operand_equal_p (v1, v2, 0))
    3805            7 :             return;
    3806              :         }
    3807              :     }
    3808              :   else
    3809              :     {
    3810           70 :       tree lhs = gimple_assign_lhs (cond_stmt);
    3811           70 :       if (!lhs || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
    3812              :         return;
    3813           70 :       gsi_next_nondebug (&gsi);
    3814           70 :       if (!gsi_end_p (gsi))
    3815              :         {
    3816           70 :           if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
    3817              :             return;
    3818           70 :           gimple *cast_stmt = gsi_stmt (gsi);
    3819           70 :           if (!gimple_assign_cast_p (cast_stmt))
    3820              :             return;
    3821           70 :           tree new_lhs = gimple_assign_lhs (cast_stmt);
    3822           70 :           gsi_next_nondebug (&gsi);
    3823           70 :           if (!gsi_end_p (gsi)
    3824           70 :               || !new_lhs
    3825           70 :               || !INTEGRAL_TYPE_P (TREE_TYPE (new_lhs))
    3826          140 :               || TYPE_PRECISION (TREE_TYPE (new_lhs)) <= 1)
    3827              :             return;
    3828              :           lhs = new_lhs;
    3829              :         }
    3830           70 :       edge succ_edge = single_succ_edge (bb);
    3831           70 :       basic_block succ_bb = succ_edge->dest;
    3832           70 :       gsi = gsi_start_phis (succ_bb);
    3833           70 :       if (gsi_end_p (gsi))
    3834              :         return;
    3835           70 :       gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
    3836           70 :       gsi_next (&gsi);
    3837           70 :       if (!gsi_end_p (gsi))
    3838              :         return;
    3839           70 :       if (gimple_phi_arg_def (phi, succ_edge->dest_idx) != lhs)
    3840              :         return;
    3841           70 :       tree other_val = gimple_phi_arg_def (phi, other_edge->dest_idx);
    3842           70 :       if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
    3843              :         {
    3844            0 :           tree cond = gimple_assign_rhs1 (cond_stmt);
    3845            0 :           if (TREE_CODE (cond) == NE_EXPR)
    3846              :             {
    3847            0 :               if (!operand_equal_p (other_val,
    3848            0 :                                     gimple_assign_rhs3 (cond_stmt), 0))
    3849              :                 return;
    3850              :             }
    3851            0 :           else if (!operand_equal_p (other_val,
    3852            0 :                                      gimple_assign_rhs2 (cond_stmt), 0))
    3853              :             return;
    3854              :         }
    3855           70 :       else if (gimple_assign_rhs_code (cond_stmt) == NE_EXPR)
    3856              :         {
    3857           41 :           if (!integer_zerop (other_val))
    3858              :             return;
    3859              :         }
    3860           29 :       else if (!integer_onep (other_val))
    3861              :         return;
    3862              :     }
    3863          110 :   if (pred_edge->flags & EDGE_TRUE_VALUE)
    3864           57 :     gimple_cond_make_true (zero_cond);
    3865              :   else
    3866           53 :     gimple_cond_make_false (zero_cond);
    3867          110 :   update_stmt (zero_cond);
    3868          110 :   reset_flow_sensitive_info_in_bb (bb);
    3869          110 :   *cfg_changed = true;
    3870              : }
    3871              : 
    3872              : /* Helper function for arith_overflow_check_p.  Return true
    3873              :    if VAL1 is equal to VAL2 cast to corresponding integral type
    3874              :    with other signedness or vice versa.  */
    3875              : 
    3876              : static bool
    3877          382 : arith_cast_equal_p (tree val1, tree val2)
    3878              : {
    3879          382 :   if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
    3880           65 :     return wi::eq_p (wi::to_wide (val1), wi::to_wide (val2));
    3881          317 :   else if (TREE_CODE (val1) != SSA_NAME || TREE_CODE (val2) != SSA_NAME)
    3882              :     return false;
    3883          279 :   if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val1))
    3884          279 :       && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val1)) == val2)
    3885              :     return true;
    3886          167 :   if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val2))
    3887          167 :       && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val2)) == val1)
    3888          120 :     return true;
    3889              :   return false;
    3890              : }
    3891              : 
    3892              : /* Helper function of match_arith_overflow.  Return 1
    3893              :    if USE_STMT is unsigned overflow check ovf != 0 for
    3894              :    STMT, -1 if USE_STMT is unsigned overflow check ovf == 0
    3895              :    and 0 otherwise.  */
    3896              : 
    3897              : static int
    3898      2957700 : arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
    3899              :                         tree maxval, tree *other)
    3900              : {
    3901      2957700 :   enum tree_code ccode = ERROR_MARK;
    3902      2957700 :   tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
    3903      2957700 :   enum tree_code code = gimple_assign_rhs_code (stmt);
    3904      5881437 :   tree lhs = gimple_assign_lhs (cast_stmt ? cast_stmt : stmt);
    3905      2957700 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    3906      2957700 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    3907      2957700 :   tree multop = NULL_TREE, divlhs = NULL_TREE;
    3908      2957700 :   gimple *cur_use_stmt = use_stmt;
    3909              : 
    3910      2957700 :   if (code == MULT_EXPR)
    3911              :     {
    3912       684318 :       if (!is_gimple_assign (use_stmt))
    3913       683966 :         return 0;
    3914       547883 :       if (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR)
    3915              :         return 0;
    3916         2217 :       if (gimple_assign_rhs1 (use_stmt) != lhs)
    3917              :         return 0;
    3918         2154 :       if (cast_stmt)
    3919              :         {
    3920          155 :           if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs1))
    3921              :             multop = rhs2;
    3922           81 :           else if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs2))
    3923              :             multop = rhs1;
    3924              :           else
    3925              :             return 0;
    3926              :         }
    3927         1999 :       else if (gimple_assign_rhs2 (use_stmt) == rhs1)
    3928              :         multop = rhs2;
    3929         1865 :       else if (operand_equal_p (gimple_assign_rhs2 (use_stmt), rhs2, 0))
    3930              :         multop = rhs1;
    3931              :       else
    3932              :         return 0;
    3933          356 :       if (stmt_ends_bb_p (use_stmt))
    3934              :         return 0;
    3935          356 :       divlhs = gimple_assign_lhs (use_stmt);
    3936          356 :       if (!divlhs)
    3937              :         return 0;
    3938          356 :       use_operand_p use;
    3939          356 :       if (!single_imm_use (divlhs, &use, &cur_use_stmt))
    3940              :         return 0;
    3941          352 :       if (cast_stmt && gimple_assign_cast_p (cur_use_stmt))
    3942              :         {
    3943            4 :           tree cast_lhs = gimple_assign_lhs (cur_use_stmt);
    3944            8 :           if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
    3945            4 :               && TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
    3946            4 :               && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
    3947            4 :                   == TYPE_PRECISION (TREE_TYPE (divlhs)))
    3948            8 :               && single_imm_use (cast_lhs, &use, &cur_use_stmt))
    3949              :             {
    3950              :               cast_stmt = NULL;
    3951              :               divlhs = cast_lhs;
    3952              :             }
    3953              :           else
    3954              :             return 0;
    3955              :         }
    3956              :     }
    3957      2273734 :   if (gimple_code (cur_use_stmt) == GIMPLE_COND)
    3958              :     {
    3959       575223 :       ccode = gimple_cond_code (cur_use_stmt);
    3960       575223 :       crhs1 = gimple_cond_lhs (cur_use_stmt);
    3961       575223 :       crhs2 = gimple_cond_rhs (cur_use_stmt);
    3962              :     }
    3963      1698511 :   else if (is_gimple_assign (cur_use_stmt))
    3964              :     {
    3965       802667 :       if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
    3966              :         {
    3967       462732 :           ccode = gimple_assign_rhs_code (cur_use_stmt);
    3968       462732 :           crhs1 = gimple_assign_rhs1 (cur_use_stmt);
    3969       462732 :           crhs2 = gimple_assign_rhs2 (cur_use_stmt);
    3970              :         }
    3971              :       else
    3972              :         return 0;
    3973              :     }
    3974              :   else
    3975              :     return 0;
    3976              : 
    3977      1037955 :   if (maxval
    3978      1037955 :       && ccode == RSHIFT_EXPR
    3979           33 :       && crhs1 == lhs
    3980           17 :       && TREE_CODE (crhs2) == INTEGER_CST
    3981      1037972 :       && wi::to_widest (crhs2) == TYPE_PRECISION (TREE_TYPE (maxval)))
    3982              :     {
    3983           16 :       tree shiftlhs = gimple_assign_lhs (use_stmt);
    3984           16 :       if (!shiftlhs)
    3985              :         return 0;
    3986           16 :       use_operand_p use;
    3987           16 :       if (!single_imm_use (shiftlhs, &use, &cur_use_stmt))
    3988              :         return 0;
    3989           12 :       if (gimple_code (cur_use_stmt) == GIMPLE_COND)
    3990              :         {
    3991            0 :           ccode = gimple_cond_code (cur_use_stmt);
    3992            0 :           crhs1 = gimple_cond_lhs (cur_use_stmt);
    3993            0 :           crhs2 = gimple_cond_rhs (cur_use_stmt);
    3994              :         }
    3995           12 :       else if (is_gimple_assign (cur_use_stmt))
    3996              :         {
    3997           12 :           if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
    3998              :             {
    3999            0 :               ccode = gimple_assign_rhs_code (cur_use_stmt);
    4000            0 :               crhs1 = gimple_assign_rhs1 (cur_use_stmt);
    4001            0 :               crhs2 = gimple_assign_rhs2 (cur_use_stmt);
    4002              :             }
    4003           12 :           else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
    4004              :             {
    4005            0 :               tree cond = gimple_assign_rhs1 (cur_use_stmt);
    4006            0 :               if (COMPARISON_CLASS_P (cond))
    4007              :                 {
    4008            0 :                   ccode = TREE_CODE (cond);
    4009            0 :                   crhs1 = TREE_OPERAND (cond, 0);
    4010            0 :                   crhs2 = TREE_OPERAND (cond, 1);
    4011              :                 }
    4012              :               else
    4013              :                 return 0;
    4014              :             }
    4015              :           else
    4016              :             {
    4017           12 :               enum tree_code sc = gimple_assign_rhs_code (cur_use_stmt);
    4018           12 :               tree castlhs = gimple_assign_lhs (cur_use_stmt);
    4019           12 :               if (!CONVERT_EXPR_CODE_P (sc)
    4020           12 :                   || !castlhs
    4021           12 :                   || !INTEGRAL_TYPE_P (TREE_TYPE (castlhs))
    4022           24 :                   || (TYPE_PRECISION (TREE_TYPE (castlhs))
    4023           12 :                       > TYPE_PRECISION (TREE_TYPE (maxval))))
    4024            0 :                 return 0;
    4025              :               return 1;
    4026              :             }
    4027              :         }
    4028              :       else
    4029              :         return 0;
    4030            0 :       if ((ccode != EQ_EXPR && ccode != NE_EXPR)
    4031            0 :           || crhs1 != shiftlhs
    4032            0 :           || !integer_zerop (crhs2))
    4033            0 :         return 0;
    4034              :       return 1;
    4035              :     }
    4036              : 
    4037      1037939 :   if (TREE_CODE_CLASS (ccode) != tcc_comparison)
    4038              :     return 0;
    4039              : 
    4040       611542 :   switch (ccode)
    4041              :     {
    4042       114160 :     case GT_EXPR:
    4043       114160 :     case LE_EXPR:
    4044       114160 :       if (maxval)
    4045              :         {
    4046              :           /* r = a + b; r > maxval or r <= maxval  */
    4047           36 :           if (crhs1 == lhs
    4048           35 :               && TREE_CODE (crhs2) == INTEGER_CST
    4049           49 :               && tree_int_cst_equal (crhs2, maxval))
    4050           13 :             return ccode == GT_EXPR ? 1 : -1;
    4051              :           break;
    4052              :         }
    4053              :       /* r = a - b; r > a or r <= a
    4054              :          r = a + b; a > r or a <= r or b > r or b <= r.  */
    4055       114124 :       if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
    4056       114064 :           || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2)
    4057         7941 :               && crhs2 == lhs))
    4058         8001 :         return ccode == GT_EXPR ? 1 : -1;
    4059              :       /* r = ~a; b > r or b <= r.  */
    4060       106123 :       if (code == BIT_NOT_EXPR && crhs2 == lhs)
    4061              :         {
    4062          232 :           if (other)
    4063          116 :             *other = crhs1;
    4064          232 :           return ccode == GT_EXPR ? 1 : -1;
    4065              :         }
    4066              :       break;
    4067        62433 :     case LT_EXPR:
    4068        62433 :     case GE_EXPR:
    4069        62433 :       if (maxval)
    4070              :         break;
    4071              :       /* r = a - b; a < r or a >= r
    4072              :          r = a + b; r < a or r >= a or r < b or r >= b.  */
    4073        62427 :       if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
    4074        62285 :           || (code == PLUS_EXPR && crhs1 == lhs
    4075        30210 :               && (crhs2 == rhs1 || crhs2 == rhs2)))
    4076         4155 :         return ccode == LT_EXPR ? 1 : -1;
    4077              :       /* r = ~a; r < b or r >= b.  */
    4078        58272 :       if (code == BIT_NOT_EXPR && crhs1 == lhs)
    4079              :         {
    4080          263 :           if (other)
    4081          140 :             *other = crhs2;
    4082          263 :           return ccode == LT_EXPR ? 1 : -1;
    4083              :         }
    4084              :       break;
    4085       434949 :     case EQ_EXPR:
    4086       434949 :     case NE_EXPR:
    4087              :       /* r = a * b; _1 = r / a; _1 == b
    4088              :          r = a * b; _1 = r / b; _1 == a
    4089              :          r = a * b; _1 = r / a; _1 != b
    4090              :          r = a * b; _1 = r / b; _1 != a.  */
    4091       434949 :       if (code == MULT_EXPR)
    4092              :         {
    4093          349 :           if (cast_stmt)
    4094              :             {
    4095          146 :               if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
    4096          146 :                   || (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
    4097              :                 {
    4098          146 :                   use_stmt = cur_use_stmt;
    4099          146 :                   return ccode == NE_EXPR ? 1 : -1;
    4100              :                 }
    4101              :             }
    4102          142 :           else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
    4103          203 :                    || (crhs2 == divlhs && crhs1 == multop))
    4104              :             {
    4105          203 :               use_stmt = cur_use_stmt;
    4106          203 :               return ccode == NE_EXPR ? 1 : -1;
    4107              :             }
    4108              :         }
    4109              :       break;
    4110              :     default:
    4111              :       break;
    4112              :     }
    4113              :   return 0;
    4114              : }
    4115              : 
    4116              : extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
    4117              : extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree));
    4118              : extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree));
    4119              : extern bool gimple_unsigned_integer_sat_mul (tree, tree*, tree (*)(tree));
    4120              : extern bool gimple_spaceship (tree, tree*, tree (*)(tree));
    4121              : 
    4122              : extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
    4123              : extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
    4124              : extern bool gimple_signed_integer_sat_trunc (tree, tree*, tree (*)(tree));
    4125              : 
    4126              : static bool
    4127          341 : build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi,
    4128              :                                                 internal_fn fn, tree lhs,
    4129              :                                                 tree op_0, tree op_1)
    4130              : {
    4131          341 :   if (direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
    4132              :     {
    4133          338 :       gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
    4134          338 :       gimple_call_set_lhs (call, lhs);
    4135          338 :       gsi_replace (gsi, call, /* update_eh_info */ true);
    4136          338 :       return true;
    4137              :     }
    4138              : 
    4139              :   return false;
    4140              : }
    4141              : 
    4142              : static bool
    4143           75 : build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi,
    4144              :                                                internal_fn fn, tree lhs,
    4145              :                                                tree op_0, tree op_1)
    4146              : {
    4147           75 :   if (!direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
    4148              :     return false;
    4149              : 
    4150           67 :   gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
    4151           67 :   gimple_call_set_lhs (call, lhs);
    4152           67 :   gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4153              : 
    4154           67 :   return true;
    4155              : }
    4156              : 
    4157              : /*
    4158              :  * Try to match saturation unsigned add with assign.
    4159              :  *   _7 = _4 + _6;
    4160              :  *   _8 = _4 > _7;
    4161              :  *   _9 = (long unsigned int) _8;
    4162              :  *   _10 = -_9;
    4163              :  *   _12 = _7 | _10;
    4164              :  *   =>
    4165              :  *   _12 = .SAT_ADD (_4, _6);
    4166              :  *
    4167              :  * Try to match IMM=-1 saturation signed add with assign.
    4168              :  * <bb 2> [local count: 1073741824]:
    4169              :  * x.0_1 = (unsigned char) x_5(D);
    4170              :  * _3 = -x.0_1;
    4171              :  * _10 = (signed char) _3;
    4172              :  * _8 = x_5(D) & _10;
    4173              :  * if (_8 < 0)
    4174              :  *   goto <bb 4>; [1.40%]
    4175              :  * else
    4176              :  *   goto <bb 3>; [98.60%]
    4177              :  * <bb 3> [local count: 434070867]:
    4178              :  * _2 = x.0_1 + 255;
    4179              :  * <bb 4> [local count: 1073741824]:
    4180              :  * # _9 = PHI <_2(3), 128(2)>
    4181              :  * _4 = (int8_t) _9;
    4182              :  *   =>
    4183              :  * _4 = .SAT_ADD (x_5, -1);
    4184              :  * Return true if the statement was replaced.  */
    4185              : 
    4186              : static bool
    4187      4972489 : match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
    4188              : {
    4189      4972489 :   tree ops[2];
    4190      4972489 :   tree lhs = gimple_assign_lhs (stmt);
    4191              : 
    4192      4972489 :   if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
    4193      4972489 :       || gimple_signed_integer_sat_add (lhs, ops, NULL))
    4194          201 :     return build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD,
    4195          201 :                                                            lhs, ops[0], ops[1]);
    4196              : 
    4197              :   return false;
    4198              : }
    4199              : 
    4200              : /*
    4201              :  * Try to match saturation add with PHI.
    4202              :  * For unsigned integer:
    4203              :  *   <bb 2> :
    4204              :  *   _1 = x_3(D) + y_4(D);
    4205              :  *   if (_1 >= x_3(D))
    4206              :  *     goto <bb 3>; [INV]
    4207              :  *   else
    4208              :  *     goto <bb 4>; [INV]
    4209              :  *
    4210              :  *   <bb 3> :
    4211              :  *
    4212              :  *   <bb 4> :
    4213              :  *   # _2 = PHI <255(2), _1(3)>
    4214              :  *   =>
    4215              :  *   <bb 4> [local count: 1073741824]:
    4216              :  *   _2 = .SAT_ADD (x_4(D), y_5(D));
    4217              :  *
    4218              :  * For signed integer:
    4219              :  *   x.0_1 = (long unsigned int) x_7(D);
    4220              :  *   y.1_2 = (long unsigned int) y_8(D);
    4221              :  *   _3 = x.0_1 + y.1_2;
    4222              :  *   sum_9 = (int64_t) _3;
    4223              :  *   _4 = x_7(D) ^ y_8(D);
    4224              :  *   _5 = x_7(D) ^ sum_9;
    4225              :  *   _15 = ~_4;
    4226              :  *   _16 = _5 & _15;
    4227              :  *   if (_16 < 0)
    4228              :  *     goto <bb 3>; [41.00%]
    4229              :  *   else
    4230              :  *     goto <bb 4>; [59.00%]
    4231              :  *   _11 = x_7(D) < 0;
    4232              :  *   _12 = (long int) _11;
    4233              :  *   _13 = -_12;
    4234              :  *   _14 = _13 ^ 9223372036854775807;
    4235              :  *   # _6 = PHI <_14(3), sum_9(2)>
    4236              :  *   =>
    4237              :  *   _6 = .SAT_ADD (x_5(D), y_6(D)); [tail call]  */
    4238              : 
    4239              : static bool
    4240      4304659 : match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
    4241              : {
    4242      4304659 :   if (gimple_phi_num_args (phi) != 2)
    4243              :     return false;
    4244              : 
    4245      3422820 :   tree ops[2];
    4246      3422820 :   tree phi_result = gimple_phi_result (phi);
    4247              : 
    4248      3422820 :   if (!gimple_unsigned_integer_sat_add (phi_result, ops, NULL)
    4249      3422820 :       && !gimple_signed_integer_sat_add (phi_result, ops, NULL))
    4250              :     return false;
    4251              : 
    4252           23 :   if (!TYPE_UNSIGNED (TREE_TYPE (ops[0])) && TREE_CODE (ops[1]) == INTEGER_CST)
    4253            0 :     ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
    4254              : 
    4255           23 :   return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_ADD,
    4256              :                                                         phi_result, ops[0],
    4257           23 :                                                         ops[1]);
    4258              : }
    4259              : 
    4260              : /*
    4261              :  * Try to match saturation unsigned sub.
    4262              :  *   _1 = _4 >= _5;
    4263              :  *   _3 = _4 - _5;
    4264              :  *   _6 = _1 ? _3 : 0;
    4265              :  *   =>
    4266              :  *   _6 = .SAT_SUB (_4, _5);
    4267              :  * Return true if the statement was replaced.  */
    4268              : 
    4269              : static bool
    4270      3710073 : match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
    4271              : {
    4272      3710073 :   tree ops[2];
    4273      3710073 :   tree lhs = gimple_assign_lhs (stmt);
    4274              : 
    4275      3710073 :   if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
    4276          140 :     return build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_SUB,
    4277          140 :                                                            lhs, ops[0], ops[1]);
    4278              : 
    4279              :   return false;
    4280              : }
    4281              : 
    4282              : /*
    4283              :  * Try to match saturation unsigned mul.
    4284              :  *   _1 = (unsigned int) a_6(D);
    4285              :  *   _2 = (unsigned int) b_7(D);
    4286              :  *   x_8 = _1 * _2;
    4287              :  *   overflow_9 = x_8 > 255;
    4288              :  *   _3 = (unsigned char) overflow_9;
    4289              :  *   _4 = -_3;
    4290              :  *   _5 = (unsigned char) x_8;
    4291              :  *   _10 = _4 | _5;
    4292              :  *   =>
    4293              :  *   _10 = .SAT_SUB (a_6, b_7);  */
    4294              : 
    4295              : static void
    4296      2659093 : match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt)
    4297              : {
    4298      2659093 :   tree ops[2];
    4299      2659093 :   tree lhs = gimple_assign_lhs (stmt);
    4300              : 
    4301      2659093 :   if (gimple_unsigned_integer_sat_mul (lhs, ops, NULL))
    4302            0 :     build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_MUL, lhs,
    4303              :                                                     ops[0], ops[1]);
    4304      2659093 : }
    4305              : 
    4306              : /* Try to match saturation unsigned mul, aka:
    4307              :      _6 = .MUL_OVERFLOW (a_4(D), b_5(D));
    4308              :      _2 = IMAGPART_EXPR <_6>;
    4309              :      if (_2 != 0)
    4310              :        goto <bb 4>; [35.00%]
    4311              :      else
    4312              :        goto <bb 3>; [65.00%]
    4313              : 
    4314              :      <bb 3> [local count: 697932184]:
    4315              :      _1 = REALPART_EXPR <_6>;
    4316              : 
    4317              :      <bb 4> [local count: 1073741824]:
    4318              :      # _3 = PHI <18446744073709551615(2), _1(3)>
    4319              :      =>
    4320              :      _3 = .SAT_MUL (a_4(D), b_5(D));  */
    4321              : 
    4322              : static bool
    4323      4304592 : match_saturation_mul (gimple_stmt_iterator *gsi, gphi *phi)
    4324              : {
    4325      4304592 :   if (gimple_phi_num_args (phi) != 2)
    4326              :     return false;
    4327              : 
    4328      3422753 :   tree ops[2];
    4329      3422753 :   tree phi_result = gimple_phi_result (phi);
    4330              : 
    4331      3422753 :   if (!gimple_unsigned_integer_sat_mul (phi_result, ops, NULL))
    4332              :     return false;
    4333              : 
    4334            0 :   return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_MUL,
    4335              :                                                         phi_result, ops[0],
    4336            0 :                                                         ops[1]);
    4337              : }
    4338              : 
    4339              : /* Try to match variants of spaceship operation:
    4340              :    <bb 2>
    4341              :    if (a_3(D) >= b_4(D)) -- CMP_1
    4342              :      goto <bb 3>;
    4343              :    else
    4344              :      goto <bb 4>;
    4345              : 
    4346              :    <bb 3>
    4347              :    _1 = a_3(D) > b_4(D); -- CMP_2
    4348              :    _5 = (int) _1;
    4349              : 
    4350              :    <bb 4>
    4351              :    # _2 = PHI <-1(2), _5(3)>
    4352              :    =>
    4353              :    _2 = .SPACESHIP (a_3(D), b_4(D), -1);
    4354              : 
    4355              :    All possible canonical variants of the comparison operator in CMP_1 and
    4356              :    CMP_2 has been included in gimple_spaceship function.  */
    4357              : static bool
    4358      4304592 : match_spaceship (gimple_stmt_iterator *gsi, gphi *phi)
    4359              : {
    4360      4304592 :   if (gimple_phi_num_args (phi) != 2)
    4361              :     return false;
    4362      3422753 :   tree ops[2];
    4363      3422753 :   tree phi_result = gimple_phi_result (phi);
    4364              : 
    4365      3422753 :   if (!gimple_spaceship (phi_result, ops, NULL))
    4366              :     return false;
    4367              : 
    4368              :   /* Allow different modes as long as both are integral types.  */
    4369          224 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
    4370          224 :       || !INTEGRAL_TYPE_P (TREE_TYPE (ops[0])))
    4371              :     return false;
    4372              : 
    4373          112 :   tree ops_type = TREE_TYPE (ops[0]);
    4374          112 :   machine_mode ops_mode = TYPE_MODE (ops_type);
    4375          112 :   machine_mode promoted_mode = ops_mode;
    4376          112 :   tree promoted_type = ops_type;
    4377          112 :   bool is_unsigned = TYPE_UNSIGNED (ops_type);
    4378              : 
    4379              :   /* Check if spaceship optab is available for the operand mode.
    4380              :      If not, try promoting to a wider mode that is supported.  */
    4381          112 :   if (optab_handler (spaceship_optab, ops_mode) == CODE_FOR_nothing)
    4382              :     {
    4383              :       /* Try promoting to wider modes (e.g., QI/HI -> SI -> DI).  */
    4384              :       machine_mode wider_mode;
    4385            0 :       FOR_EACH_WIDER_MODE_FROM (wider_mode, ops_mode)
    4386              :         {
    4387            0 :           if (optab_handler (spaceship_optab, wider_mode)
    4388              :               != CODE_FOR_nothing)
    4389              :             {
    4390              :               /* Check if we can get a type for this mode with matching
    4391              :                  signedness.  */
    4392            0 :               promoted_type = lang_hooks.types.type_for_mode (wider_mode,
    4393              :                                                               is_unsigned);
    4394            0 :               if (promoted_type != NULL_TREE && INTEGRAL_TYPE_P (promoted_type))
    4395              :                 {
    4396              :                   promoted_mode = wider_mode;
    4397              :                   break;
    4398              :                 }
    4399              :             }
    4400              :         }
    4401              : 
    4402              :       // If no suitable promoted mode found, give up.
    4403            0 :       if (promoted_mode == ops_mode)
    4404      4304592 :         return false;
    4405              :     }
    4406              : 
    4407              :   /* If promotion is needed, insert conversion statements.
    4408              :      We must use GIMPLE assignments rather than fold_convert because
    4409              :      gimple_call arguments must be valid GIMPLE values (SSA names or
    4410              :      constants), not tree expressions.  */
    4411          112 :   ops[0] = gimple_convert (gsi, true, GSI_SAME_STMT, UNKNOWN_LOCATION,
    4412              :                            promoted_type, ops[0]);
    4413          112 :   ops[1] = gimple_convert (gsi, true, GSI_SAME_STMT, UNKNOWN_LOCATION,
    4414              :                            promoted_type, ops[1]);
    4415              : 
    4416          112 :   tree spaceship_arg_3 = is_unsigned ? build_one_cst (integer_type_node)
    4417           96 :     : build_minus_one_cst (integer_type_node);
    4418              : 
    4419          112 :   gcall *call = gimple_build_call_internal (IFN_SPACESHIP, 3, ops[0], ops[1],
    4420              :                                             spaceship_arg_3);
    4421              : 
    4422              :   /* SPACESHIP optab always returns signed int (SI mode).
    4423              :      Cast to phi_result's type if needed.  */
    4424          112 :   tree call_result_type = integer_type_node;
    4425          112 :   if (!types_compatible_p (TREE_TYPE (phi_result), call_result_type))
    4426              :     {
    4427           48 :       tree call_result = make_ssa_name (call_result_type);
    4428           48 :       gimple_call_set_lhs (call, call_result);
    4429           48 :       gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4430           48 :       gassign *cast_stmt = gimple_build_assign (phi_result, NOP_EXPR,
    4431              :                                                 call_result);
    4432           48 :       gsi_insert_before (gsi, cast_stmt, GSI_SAME_STMT);
    4433              :     }
    4434              :   else
    4435              :     {
    4436           64 :       gimple_call_set_lhs (call, phi_result);
    4437           64 :       gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4438              :     }
    4439              :   return true;
    4440              : }
    4441              : 
    4442              : 
    4443              : /*
    4444              :  * Try to match saturation unsigned sub.
    4445              :  *  <bb 2> [local count: 1073741824]:
    4446              :  *  if (x_2(D) > y_3(D))
    4447              :  *    goto <bb 3>; [50.00%]
    4448              :  *  else
    4449              :  *    goto <bb 4>; [50.00%]
    4450              :  *
    4451              :  *  <bb 3> [local count: 536870912]:
    4452              :  *  _4 = x_2(D) - y_3(D);
    4453              :  *
    4454              :  *  <bb 4> [local count: 1073741824]:
    4455              :  *  # _1 = PHI <0(2), _4(3)>
    4456              :  *  =>
    4457              :  *  <bb 4> [local count: 1073741824]:
    4458              :  *  _1 = .SAT_SUB (x_2(D), y_3(D));  */
    4459              : static bool
    4460      4304640 : match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
    4461              : {
    4462      4304640 :   if (gimple_phi_num_args (phi) != 2)
    4463              :     return false;
    4464              : 
    4465      3422801 :   tree ops[2];
    4466      3422801 :   tree phi_result = gimple_phi_result (phi);
    4467              : 
    4468      3422801 :   if (!gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
    4469      3422801 :       && !gimple_signed_integer_sat_sub (phi_result, ops, NULL))
    4470              :     return false;
    4471              : 
    4472           52 :   return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_SUB,
    4473              :                                                         phi_result, ops[0],
    4474           52 :                                                         ops[1]);
    4475              : }
    4476              : 
    4477              : /*
    4478              :  * Try to match saturation unsigned sub.
    4479              :  * uint16_t x_4(D);
    4480              :  * uint8_t _6;
    4481              :  * overflow_5 = x_4(D) > 255;
    4482              :  * _1 = (unsigned char) x_4(D);
    4483              :  * _2 = (unsigned char) overflow_5;
    4484              :  * _3 = -_2;
    4485              :  * _6 = _1 | _3;
    4486              :  * =>
    4487              :  * _6 = .SAT_TRUNC (x_4(D));
    4488              :  * */
    4489              : static void
    4490      2659093 : match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
    4491              : {
    4492      2659093 :   tree ops[1];
    4493      2659093 :   tree lhs = gimple_assign_lhs (stmt);
    4494      2659093 :   tree type = TREE_TYPE (lhs);
    4495              : 
    4496      2659093 :   if (gimple_unsigned_integer_sat_trunc (lhs, ops, NULL)
    4497      2659228 :     && direct_internal_fn_supported_p (IFN_SAT_TRUNC,
    4498          135 :                                        tree_pair (type, TREE_TYPE (ops[0])),
    4499              :                                        OPTIMIZE_FOR_BOTH))
    4500              :     {
    4501          108 :       gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
    4502          108 :       gimple_call_set_lhs (call, lhs);
    4503          108 :       gsi_replace (gsi, call, /* update_eh_info */ true);
    4504              :     }
    4505      2659093 : }
    4506              : 
    4507              : /*
    4508              :  * Try to match saturation truncate.
    4509              :  * Aka:
    4510              :  *   x.0_1 = (unsigned long) x_4(D);
    4511              :  *   _2 = x.0_1 + 2147483648;
    4512              :  *   if (_2 > 4294967295)
    4513              :  *     goto <bb 4>; [50.00%]
    4514              :  *   else
    4515              :  *     goto <bb 3>; [50.00%]
    4516              :  * ;;    succ:       4
    4517              :  * ;;                3
    4518              :  *
    4519              :  * ;;   basic block 3, loop depth 0
    4520              :  * ;;    pred:       2
    4521              :  *   trunc_5 = (int32_t) x_4(D);
    4522              :  *   goto <bb 5>; [100.00%]
    4523              :  * ;;    succ:       5
    4524              :  *
    4525              :  * ;;   basic block 4, loop depth 0
    4526              :  * ;;    pred:       2
    4527              :  *   _7 = x_4(D) < 0;
    4528              :  *   _8 = (int) _7;
    4529              :  *   _9 = -_8;
    4530              :  *   _10 = _9 ^ 2147483647;
    4531              :  * ;;    succ:       5
    4532              :  *
    4533              :  * ;;   basic block 5, loop depth 0
    4534              :  * ;;    pred:       3
    4535              :  * ;;                4
    4536              :  *   # _3 = PHI <trunc_5(3), _10(4)>
    4537              :  * =>
    4538              :  * _6 = .SAT_TRUNC (x_4(D));
    4539              :  */
    4540              : 
    4541              : static bool
    4542      4304592 : match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
    4543              : {
    4544      4304592 :   if (gimple_phi_num_args (phi) != 2)
    4545              :     return false;
    4546              : 
    4547      3422753 :   tree ops[1];
    4548      3422753 :   tree phi_result = gimple_phi_result (phi);
    4549      3422753 :   tree type = TREE_TYPE (phi_result);
    4550              : 
    4551      3422753 :   if (!gimple_unsigned_integer_sat_trunc (phi_result, ops, NULL)
    4552      3422753 :       && !gimple_signed_integer_sat_trunc (phi_result, ops, NULL))
    4553              :     return false;
    4554              : 
    4555            0 :   if (!direct_internal_fn_supported_p (IFN_SAT_TRUNC,
    4556            0 :                                        tree_pair (type, TREE_TYPE (ops[0])),
    4557              :                                        OPTIMIZE_FOR_BOTH))
    4558              :     return false;
    4559              : 
    4560            0 :   gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
    4561            0 :   gimple_call_set_lhs (call, phi_result);
    4562            0 :   gsi_insert_before (gsi, call, GSI_SAME_STMT);
    4563              : 
    4564            0 :   return true;
    4565              : }
    4566              : 
    4567              : /* Recognize for unsigned x
    4568              :    x = y - z;
    4569              :    if (x > y)
    4570              :    where there are other uses of x and replace it with
    4571              :    _7 = .SUB_OVERFLOW (y, z);
    4572              :    x = REALPART_EXPR <_7>;
    4573              :    _8 = IMAGPART_EXPR <_7>;
    4574              :    if (_8)
    4575              :    and similarly for addition.
    4576              : 
    4577              :    Also recognize:
    4578              :    yc = (type) y;
    4579              :    zc = (type) z;
    4580              :    x = yc + zc;
    4581              :    if (x > max)
    4582              :    where y and z have unsigned types with maximum max
    4583              :    and there are other uses of x and all of those cast x
    4584              :    back to that unsigned type and again replace it with
    4585              :    _7 = .ADD_OVERFLOW (y, z);
    4586              :    _9 = REALPART_EXPR <_7>;
    4587              :    _8 = IMAGPART_EXPR <_7>;
    4588              :    if (_8)
    4589              :    and replace (utype) x with _9.
    4590              :    Or with x >> popcount (max) instead of x > max.
    4591              : 
    4592              :    Also recognize:
    4593              :    x = ~z;
    4594              :    if (y > x)
    4595              :    and replace it with
    4596              :    _7 = .ADD_OVERFLOW (y, z);
    4597              :    _8 = IMAGPART_EXPR <_7>;
    4598              :    if (_8)
    4599              : 
    4600              :    And also recognize:
    4601              :    z = x * y;
    4602              :    if (x != 0)
    4603              :      goto <bb 3>; [50.00%]
    4604              :    else
    4605              :      goto <bb 4>; [50.00%]
    4606              : 
    4607              :    <bb 3> [local count: 536870913]:
    4608              :    _2 = z / x;
    4609              :    _9 = _2 != y;
    4610              :    _10 = (int) _9;
    4611              : 
    4612              :    <bb 4> [local count: 1073741824]:
    4613              :    # iftmp.0_3 = PHI <_10(3), 0(2)>
    4614              :    and replace it with
    4615              :    _7 = .MUL_OVERFLOW (x, y);
    4616              :    z = IMAGPART_EXPR <_7>;
    4617              :    _8 = IMAGPART_EXPR <_7>;
    4618              :    _9 = _8 != 0;
    4619              :    iftmp.0_3 = (int) _9;  */
    4620              : 
    4621              : static bool
    4622      3398670 : match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
    4623              :                       enum tree_code code, bool *cfg_changed)
    4624              : {
    4625      3398670 :   tree lhs = gimple_assign_lhs (stmt);
    4626      3398670 :   tree type = TREE_TYPE (lhs);
    4627      3398670 :   use_operand_p use_p;
    4628      3398670 :   imm_use_iterator iter;
    4629      3398670 :   bool use_seen = false;
    4630      3398670 :   bool ovf_use_seen = false;
    4631      3398670 :   gimple *use_stmt;
    4632      3398670 :   gimple *add_stmt = NULL;
    4633      3398670 :   bool add_first = false;
    4634      3398670 :   gimple *cond_stmt = NULL;
    4635      3398670 :   gimple *cast_stmt = NULL;
    4636      3398670 :   tree cast_lhs = NULL_TREE;
    4637              : 
    4638      3398670 :   gcc_checking_assert (code == PLUS_EXPR
    4639              :                        || code == MINUS_EXPR
    4640              :                        || code == MULT_EXPR
    4641              :                        || code == BIT_NOT_EXPR);
    4642      3398670 :   if (!INTEGRAL_TYPE_P (type)
    4643      2872150 :       || !TYPE_UNSIGNED (type)
    4644      1977464 :       || has_zero_uses (lhs)
    4645      3398670 :       || (code != PLUS_EXPR
    4646      1976972 :           && code != MULT_EXPR
    4647       173660 :           && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab,
    4648       147586 :                             TYPE_MODE (type)) == CODE_FOR_nothing))
    4649              :     return false;
    4650              : 
    4651      1975162 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    4652      1975162 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    4653      5459260 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    4654              :     {
    4655      3490077 :       use_stmt = USE_STMT (use_p);
    4656      3490077 :       if (is_gimple_debug (use_stmt))
    4657       584712 :         continue;
    4658              : 
    4659      2905365 :       tree other = NULL_TREE;
    4660      2905365 :       if (arith_overflow_check_p (stmt, NULL, use_stmt, NULL_TREE, &other))
    4661              :         {
    4662         6554 :           if (code == BIT_NOT_EXPR)
    4663              :             {
    4664          256 :               gcc_assert (other);
    4665          256 :               if (TREE_CODE (other) != SSA_NAME)
    4666            0 :                 return false;
    4667          256 :               if (rhs2 == NULL)
    4668          256 :                 rhs2 = other;
    4669              :               else
    4670              :                 return false;
    4671          256 :               cond_stmt = use_stmt;
    4672              :             }
    4673              :           ovf_use_seen = true;
    4674              :         }
    4675              :       else
    4676              :         {
    4677      2898811 :           use_seen = true;
    4678      2898811 :           if (code == MULT_EXPR
    4679      2898811 :               && cast_stmt == NULL
    4680      2898811 :               && gimple_assign_cast_p (use_stmt))
    4681              :             {
    4682        32815 :               cast_lhs = gimple_assign_lhs (use_stmt);
    4683        65630 :               if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
    4684        32268 :                   && !TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
    4685        60312 :                   && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
    4686        27497 :                       == TYPE_PRECISION (TREE_TYPE (lhs))))
    4687              :                 cast_stmt = use_stmt;
    4688              :               else
    4689              :                 cast_lhs = NULL_TREE;
    4690              :             }
    4691              :         }
    4692      2905365 :       if (ovf_use_seen && use_seen)
    4693              :         break;
    4694            0 :     }
    4695              : 
    4696      1975162 :   if (!ovf_use_seen
    4697      1975162 :       && code == MULT_EXPR
    4698       455945 :       && cast_stmt)
    4699              :     {
    4700        27146 :       if (TREE_CODE (rhs1) != SSA_NAME
    4701        27146 :           || (TREE_CODE (rhs2) != SSA_NAME && TREE_CODE (rhs2) != INTEGER_CST))
    4702              :         return false;
    4703        62752 :       FOR_EACH_IMM_USE_FAST (use_p, iter, cast_lhs)
    4704              :         {
    4705        35606 :           use_stmt = USE_STMT (use_p);
    4706        35606 :           if (is_gimple_debug (use_stmt))
    4707         1740 :             continue;
    4708              : 
    4709        33866 :           if (arith_overflow_check_p (stmt, cast_stmt, use_stmt,
    4710              :                                       NULL_TREE, NULL))
    4711        35606 :             ovf_use_seen = true;
    4712        27146 :         }
    4713        27146 :     }
    4714              :   else
    4715              :     {
    4716              :       cast_stmt = NULL;
    4717              :       cast_lhs = NULL_TREE;
    4718              :     }
    4719              : 
    4720      1975162 :   tree maxval = NULL_TREE;
    4721      1975162 :   if (!ovf_use_seen
    4722        13061 :       || (code != MULT_EXPR && (code == BIT_NOT_EXPR ? use_seen : !use_seen))
    4723         6166 :       || (code == PLUS_EXPR
    4724         5827 :           && optab_handler (uaddv4_optab,
    4725         5827 :                             TYPE_MODE (type)) == CODE_FOR_nothing)
    4726      1987936 :       || (code == MULT_EXPR
    4727          235 :           && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
    4728          155 :                             TYPE_MODE (type)) == CODE_FOR_nothing
    4729            3 :           && (use_seen
    4730            3 :               || cast_stmt
    4731            0 :               || !can_mult_highpart_p (TYPE_MODE (type), true))))
    4732              :     {
    4733      1968844 :       if (code != PLUS_EXPR)
    4734              :         return false;
    4735      1367534 :       if (TREE_CODE (rhs1) != SSA_NAME
    4736      1367534 :           || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
    4737              :         return false;
    4738       322718 :       rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
    4739       322718 :       tree type1 = TREE_TYPE (rhs1);
    4740       322718 :       if (!INTEGRAL_TYPE_P (type1)
    4741       168856 :           || !TYPE_UNSIGNED (type1)
    4742        32352 :           || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
    4743       336939 :           || (TYPE_PRECISION (type1)
    4744       336939 :               != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
    4745              :         return false;
    4746         9537 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    4747              :         {
    4748         3924 :           if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
    4749         3924 :                                     TYPE_PRECISION (type1),
    4750         7848 :                                     UNSIGNED), 0))
    4751              :             return false;
    4752         1420 :           rhs2 = fold_convert (type1, rhs2);
    4753              :         }
    4754              :       else
    4755              :         {
    4756         5613 :           if (TREE_CODE (rhs2) != SSA_NAME
    4757         5613 :               || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
    4758              :             return false;
    4759         2410 :           rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
    4760         2410 :           tree type2 = TREE_TYPE (rhs2);
    4761         2410 :           if (!INTEGRAL_TYPE_P (type2)
    4762         1033 :               || !TYPE_UNSIGNED (type2)
    4763          332 :               || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
    4764         2714 :               || (TYPE_PRECISION (type2)
    4765         2714 :                   != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
    4766              :             return false;
    4767              :         }
    4768         1711 :       if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
    4769              :         type = type1;
    4770              :       else
    4771            3 :         type = TREE_TYPE (rhs2);
    4772              : 
    4773         1711 :       if (TREE_CODE (type) != INTEGER_TYPE
    4774         3422 :           || optab_handler (uaddv4_optab,
    4775         1711 :                             TYPE_MODE (type)) == CODE_FOR_nothing)
    4776              :         return false;
    4777              : 
    4778         1711 :       maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
    4779              :                                                       UNSIGNED));
    4780         1711 :       ovf_use_seen = false;
    4781         1711 :       use_seen = false;
    4782         1711 :       basic_block use_bb = NULL;
    4783         1914 :       FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    4784              :         {
    4785         1853 :           use_stmt = USE_STMT (use_p);
    4786         1853 :           if (is_gimple_debug (use_stmt))
    4787          138 :             continue;
    4788              : 
    4789         1715 :           if (arith_overflow_check_p (stmt, NULL, use_stmt, maxval, NULL))
    4790              :             {
    4791           13 :               ovf_use_seen = true;
    4792           13 :               use_bb = gimple_bb (use_stmt);
    4793              :             }
    4794              :           else
    4795              :             {
    4796         1702 :               if (!gimple_assign_cast_p (use_stmt)
    4797         1702 :                   || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
    4798              :                 return false;
    4799          113 :               tree use_lhs = gimple_assign_lhs (use_stmt);
    4800          226 :               if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
    4801          226 :                   || (TYPE_PRECISION (TREE_TYPE (use_lhs))
    4802          113 :                       > TYPE_PRECISION (type)))
    4803              :                 return false;
    4804              :               use_seen = true;
    4805              :             }
    4806         1650 :         }
    4807           61 :       if (!ovf_use_seen)
    4808              :         return false;
    4809           13 :       if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
    4810              :         {
    4811            2 :           if (!use_seen)
    4812              :             return false;
    4813            2 :           tree new_rhs1 = make_ssa_name (type);
    4814            2 :           gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
    4815            2 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4816            2 :           rhs1 = new_rhs1;
    4817              :         }
    4818           11 :       else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
    4819              :         {
    4820            2 :           if (!use_seen)
    4821              :             return false;
    4822            2 :           tree new_rhs2 = make_ssa_name (type);
    4823            2 :           gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
    4824            2 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4825            2 :           rhs2 = new_rhs2;
    4826              :         }
    4827            9 :       else if (!use_seen)
    4828              :         {
    4829              :           /* If there are no uses of the wider addition, check if
    4830              :              forwprop has not created a narrower addition.
    4831              :              Require it to be in the same bb as the overflow check.  */
    4832           12 :           FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
    4833              :             {
    4834           11 :               use_stmt = USE_STMT (use_p);
    4835           11 :               if (is_gimple_debug (use_stmt))
    4836            0 :                 continue;
    4837              : 
    4838           11 :               if (use_stmt == stmt)
    4839            0 :                 continue;
    4840              : 
    4841           11 :               if (!is_gimple_assign (use_stmt)
    4842           11 :                   || gimple_bb (use_stmt) != use_bb
    4843           22 :                   || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
    4844            3 :                 continue;
    4845              : 
    4846            8 :               if (gimple_assign_rhs1 (use_stmt) == rhs1)
    4847              :                 {
    4848            8 :                   if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
    4849              :                                         rhs2, 0))
    4850            0 :                     continue;
    4851              :                 }
    4852            0 :               else if (gimple_assign_rhs2 (use_stmt) == rhs1)
    4853              :                 {
    4854            0 :                   if (gimple_assign_rhs1 (use_stmt) != rhs2)
    4855            0 :                     continue;
    4856              :                 }
    4857              :               else
    4858            0 :                 continue;
    4859              : 
    4860            8 :               add_stmt = use_stmt;
    4861            8 :               break;
    4862            9 :             }
    4863            9 :           if (add_stmt == NULL)
    4864              :             return false;
    4865              : 
    4866              :           /* If stmt and add_stmt are in the same bb, we need to find out
    4867              :              which one is earlier.  If they are in different bbs, we've
    4868              :              checked add_stmt is in the same bb as one of the uses of the
    4869              :              stmt lhs, so stmt needs to dominate add_stmt too.  */
    4870            8 :           if (gimple_bb (stmt) == gimple_bb (add_stmt))
    4871              :             {
    4872            8 :               gimple_stmt_iterator gsif = *gsi;
    4873            8 :               gimple_stmt_iterator gsib = *gsi;
    4874            8 :               int i;
    4875              :               /* Search both forward and backward from stmt and have a small
    4876              :                  upper bound.  */
    4877           20 :               for (i = 0; i < 128; i++)
    4878              :                 {
    4879           20 :                   if (!gsi_end_p (gsib))
    4880              :                     {
    4881           18 :                       gsi_prev_nondebug (&gsib);
    4882           18 :                       if (gsi_stmt (gsib) == add_stmt)
    4883              :                         {
    4884              :                           add_first = true;
    4885              :                           break;
    4886              :                         }
    4887              :                     }
    4888            2 :                   else if (gsi_end_p (gsif))
    4889              :                     break;
    4890           18 :                   if (!gsi_end_p (gsif))
    4891              :                     {
    4892           18 :                       gsi_next_nondebug (&gsif);
    4893           18 :                       if (gsi_stmt (gsif) == add_stmt)
    4894              :                         break;
    4895              :                     }
    4896              :                 }
    4897            8 :               if (i == 128)
    4898            0 :                 return false;
    4899            8 :               if (add_first)
    4900            2 :                 *gsi = gsi_for_stmt (add_stmt);
    4901              :             }
    4902              :         }
    4903              :     }
    4904              : 
    4905         6330 :   if (code == BIT_NOT_EXPR)
    4906          239 :     *gsi = gsi_for_stmt (cond_stmt);
    4907              : 
    4908         6330 :   auto_vec<gimple *, 8> mul_stmts;
    4909         6330 :   if (code == MULT_EXPR && cast_stmt)
    4910              :     {
    4911           75 :       type = TREE_TYPE (cast_lhs);
    4912           75 :       gimple *g = SSA_NAME_DEF_STMT (rhs1);
    4913           75 :       if (gimple_assign_cast_p (g)
    4914           38 :           && useless_type_conversion_p (type,
    4915           38 :                                         TREE_TYPE (gimple_assign_rhs1 (g)))
    4916          113 :           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
    4917              :         rhs1 = gimple_assign_rhs1 (g);
    4918              :       else
    4919              :         {
    4920           37 :           g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs1);
    4921           37 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4922           37 :           rhs1 = gimple_assign_lhs (g);
    4923           37 :           mul_stmts.quick_push (g);
    4924              :         }
    4925           75 :       if (TREE_CODE (rhs2) == INTEGER_CST)
    4926           32 :         rhs2 = fold_convert (type, rhs2);
    4927              :       else
    4928              :         {
    4929           43 :           g = SSA_NAME_DEF_STMT (rhs2);
    4930           43 :           if (gimple_assign_cast_p (g)
    4931           22 :               && useless_type_conversion_p (type,
    4932           22 :                                             TREE_TYPE (gimple_assign_rhs1 (g)))
    4933           65 :               && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
    4934              :             rhs2 = gimple_assign_rhs1 (g);
    4935              :           else
    4936              :             {
    4937           21 :               g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs2);
    4938           21 :               gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4939           21 :               rhs2 = gimple_assign_lhs (g);
    4940           21 :               mul_stmts.quick_push (g);
    4941              :             }
    4942              :         }
    4943              :     }
    4944         6330 :   internal_fn ifn = (code == MULT_EXPR
    4945         6330 :                      ? IFN_MUL_OVERFLOW
    4946              :                      : code != MINUS_EXPR
    4947         6178 :                      ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW);
    4948              :   if (code != MINUS_EXPR
    4949         6230 :       && tree_swap_operands_p (rhs1, rhs2))
    4950              :     std::swap (rhs1, rhs2);
    4951              : 
    4952         6330 :   tree ctype = build_complex_type (type);
    4953         6330 :   gcall *g = gimple_build_call_internal (ifn, 2, rhs1, rhs2);
    4954         6330 :   tree ctmp = make_ssa_name (ctype);
    4955         6330 :   gimple_call_set_lhs (g, ctmp);
    4956         6330 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    4957         6330 :   tree new_lhs = (maxval || cast_stmt) ? make_ssa_name (type) : lhs;
    4958         6330 :   gassign *g2;
    4959         6330 :   if (code != BIT_NOT_EXPR)
    4960              :     {
    4961         6091 :       g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
    4962              :                                 build1 (REALPART_EXPR, type, ctmp));
    4963         6091 :       if (maxval || cast_stmt)
    4964              :         {
    4965           87 :           gsi_insert_before (gsi, g2, GSI_SAME_STMT);
    4966           87 :           if (add_first)
    4967            2 :             *gsi = gsi_for_stmt (stmt);
    4968              :         }
    4969              :       else
    4970         6004 :         gsi_replace (gsi, g2, true);
    4971         6091 :       if (code == MULT_EXPR)
    4972              :         {
    4973          152 :           mul_stmts.quick_push (g);
    4974          152 :           mul_stmts.quick_push (g2);
    4975          152 :           if (cast_stmt)
    4976              :             {
    4977           75 :               g2 = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
    4978           75 :               gsi_replace (gsi, g2, true);
    4979           75 :               mul_stmts.quick_push (g2);
    4980              :             }
    4981              :         }
    4982              :     }
    4983         6330 :   tree ovf = make_ssa_name (type);
    4984         6330 :   g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
    4985              :                             build1 (IMAGPART_EXPR, type, ctmp));
    4986         6330 :   if (code != BIT_NOT_EXPR)
    4987         6091 :     gsi_insert_after (gsi, g2, GSI_NEW_STMT);
    4988              :   else
    4989          239 :     gsi_insert_before (gsi, g2, GSI_SAME_STMT);
    4990         6330 :   if (code == MULT_EXPR)
    4991          152 :     mul_stmts.quick_push (g2);
    4992              : 
    4993        33623 :   FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
    4994              :     {
    4995        21038 :       if (is_gimple_debug (use_stmt))
    4996         4284 :         continue;
    4997              : 
    4998        16754 :       gimple *orig_use_stmt = use_stmt;
    4999        16754 :       int ovf_use = arith_overflow_check_p (stmt, cast_stmt, use_stmt,
    5000              :                                             maxval, NULL);
    5001        16754 :       if (ovf_use == 0)
    5002              :         {
    5003        10371 :           gcc_assert (code != BIT_NOT_EXPR);
    5004        10371 :           if (maxval)
    5005              :             {
    5006            4 :               tree use_lhs = gimple_assign_lhs (use_stmt);
    5007            4 :               gimple_assign_set_rhs1 (use_stmt, new_lhs);
    5008            4 :               if (useless_type_conversion_p (TREE_TYPE (use_lhs),
    5009            4 :                                              TREE_TYPE (new_lhs)))
    5010            4 :                 gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
    5011            4 :               update_stmt (use_stmt);
    5012              :             }
    5013        10371 :           continue;
    5014        10371 :         }
    5015         6383 :       if (gimple_code (use_stmt) == GIMPLE_COND)
    5016              :         {
    5017         4230 :           gcond *cond_stmt = as_a <gcond *> (use_stmt);
    5018         4230 :           gimple_cond_set_lhs (cond_stmt, ovf);
    5019         4230 :           gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
    5020         4460 :           gimple_cond_set_code (cond_stmt, ovf_use == 1 ? NE_EXPR : EQ_EXPR);
    5021              :         }
    5022              :       else
    5023              :         {
    5024         2153 :           gcc_checking_assert (is_gimple_assign (use_stmt));
    5025         2153 :           if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
    5026              :             {
    5027         2153 :               if (gimple_assign_rhs_code (use_stmt) == RSHIFT_EXPR)
    5028              :                 {
    5029            6 :                   g2 = gimple_build_assign (make_ssa_name (boolean_type_node),
    5030              :                                             ovf_use == 1 ? NE_EXPR : EQ_EXPR,
    5031              :                                             ovf, build_int_cst (type, 0));
    5032            6 :                   gimple_stmt_iterator gsiu = gsi_for_stmt (use_stmt);
    5033            6 :                   gsi_insert_before (&gsiu, g2, GSI_SAME_STMT);
    5034            6 :                   gimple_assign_set_rhs_with_ops (&gsiu, NOP_EXPR,
    5035              :                                                   gimple_assign_lhs (g2));
    5036            6 :                   update_stmt (use_stmt);
    5037            6 :                   use_operand_p use;
    5038            6 :                   single_imm_use (gimple_assign_lhs (use_stmt), &use,
    5039              :                                   &use_stmt);
    5040            6 :                   if (gimple_code (use_stmt) == GIMPLE_COND)
    5041              :                     {
    5042            0 :                       gcond *cond_stmt = as_a <gcond *> (use_stmt);
    5043            0 :                       gimple_cond_set_lhs (cond_stmt, ovf);
    5044            0 :                       gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
    5045              :                     }
    5046              :                   else
    5047              :                     {
    5048            6 :                       gcc_checking_assert (is_gimple_assign (use_stmt));
    5049            6 :                       if (gimple_assign_rhs_class (use_stmt)
    5050              :                           == GIMPLE_BINARY_RHS)
    5051              :                         {
    5052            0 :                           gimple_assign_set_rhs1 (use_stmt, ovf);
    5053            0 :                           gimple_assign_set_rhs2 (use_stmt,
    5054              :                                                   build_int_cst (type, 0));
    5055              :                         }
    5056            6 :                       else if (gimple_assign_cast_p (use_stmt))
    5057            6 :                         gimple_assign_set_rhs1 (use_stmt, ovf);
    5058              :                       else
    5059              :                         {
    5060            0 :                           tree_code sc = gimple_assign_rhs_code (use_stmt);
    5061            0 :                           gcc_checking_assert (sc == COND_EXPR);
    5062            0 :                           tree cond = gimple_assign_rhs1 (use_stmt);
    5063            0 :                           cond = build2 (TREE_CODE (cond),
    5064              :                                          boolean_type_node, ovf,
    5065              :                                          build_int_cst (type, 0));
    5066            0 :                           gimple_assign_set_rhs1 (use_stmt, cond);
    5067              :                         }
    5068              :                     }
    5069            6 :                   update_stmt (use_stmt);
    5070            6 :                   gsi_remove (&gsiu, true);
    5071            6 :                   gsiu = gsi_for_stmt (g2);
    5072            6 :                   gsi_remove (&gsiu, true);
    5073            6 :                   continue;
    5074            6 :                 }
    5075              :               else
    5076              :                 {
    5077         2147 :                   gimple_assign_set_rhs1 (use_stmt, ovf);
    5078         2147 :                   gimple_assign_set_rhs2 (use_stmt, build_int_cst (type, 0));
    5079         2219 :                   gimple_assign_set_rhs_code (use_stmt,
    5080              :                                               ovf_use == 1
    5081              :                                               ? NE_EXPR : EQ_EXPR);
    5082              :                 }
    5083              :             }
    5084              :           else
    5085              :             {
    5086            0 :               gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
    5087              :                                    == COND_EXPR);
    5088            0 :               tree cond = build2 (ovf_use == 1 ? NE_EXPR : EQ_EXPR,
    5089              :                                   boolean_type_node, ovf,
    5090              :                                   build_int_cst (type, 0));
    5091            0 :               gimple_assign_set_rhs1 (use_stmt, cond);
    5092              :             }
    5093              :         }
    5094         6377 :       update_stmt (use_stmt);
    5095         6377 :       if (code == MULT_EXPR && use_stmt != orig_use_stmt)
    5096              :         {
    5097          173 :           gimple_stmt_iterator gsi2 = gsi_for_stmt (orig_use_stmt);
    5098          173 :           maybe_optimize_guarding_check (mul_stmts, use_stmt, orig_use_stmt,
    5099              :                                          cfg_changed);
    5100          173 :           use_operand_p use;
    5101          173 :           gimple *cast_stmt;
    5102          173 :           if (single_imm_use (gimple_assign_lhs (orig_use_stmt), &use,
    5103              :                               &cast_stmt)
    5104          173 :               && gimple_assign_cast_p (cast_stmt))
    5105              :             {
    5106            2 :               gimple_stmt_iterator gsi3 = gsi_for_stmt (cast_stmt);
    5107            2 :               gsi_remove (&gsi3, true);
    5108            2 :               release_ssa_name (gimple_assign_lhs (cast_stmt));
    5109              :             }
    5110          173 :           gsi_remove (&gsi2, true);
    5111          173 :           release_ssa_name (gimple_assign_lhs (orig_use_stmt));
    5112              :         }
    5113         6330 :     }
    5114         6330 :   if (maxval)
    5115              :     {
    5116           12 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
    5117           12 :       gsi_remove (&gsi2, true);
    5118           12 :       if (add_stmt)
    5119              :         {
    5120            8 :           gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
    5121              :                                            new_lhs);
    5122            8 :           gsi2 = gsi_for_stmt (add_stmt);
    5123            8 :           gsi_replace (&gsi2, g, true);
    5124              :         }
    5125              :     }
    5126         6318 :   else if (code == BIT_NOT_EXPR)
    5127              :     {
    5128          239 :       *gsi = gsi_for_stmt (stmt);
    5129          239 :       gsi_remove (gsi, true);
    5130          239 :       release_ssa_name (lhs);
    5131          239 :       return true;
    5132              :     }
    5133              :   return false;
    5134         6330 : }
    5135              : 
    5136              : /* Helper of match_uaddc_usubc.  Look through an integral cast
    5137              :    which should preserve [0, 1] range value (unless source has
    5138              :    1-bit signed type) and the cast has single use.  */
    5139              : 
    5140              : static gimple *
    5141      2093392 : uaddc_cast (gimple *g)
    5142              : {
    5143      2093392 :   if (!gimple_assign_cast_p (g))
    5144              :     return g;
    5145       500214 :   tree op = gimple_assign_rhs1 (g);
    5146       500214 :   if (TREE_CODE (op) == SSA_NAME
    5147       421474 :       && INTEGRAL_TYPE_P (TREE_TYPE (op))
    5148       288716 :       && (TYPE_PRECISION (TREE_TYPE (op)) > 1
    5149         5809 :           || TYPE_UNSIGNED (TREE_TYPE (op)))
    5150       788930 :       && has_single_use (gimple_assign_lhs (g)))
    5151       180869 :     return SSA_NAME_DEF_STMT (op);
    5152              :   return g;
    5153              : }
    5154              : 
    5155              : /* Helper of match_uaddc_usubc.  Look through a NE_EXPR
    5156              :    comparison with 0 which also preserves [0, 1] value range.  */
    5157              : 
    5158              : static gimple *
    5159      2093552 : uaddc_ne0 (gimple *g)
    5160              : {
    5161      2093552 :   if (is_gimple_assign (g)
    5162      1286641 :       && gimple_assign_rhs_code (g) == NE_EXPR
    5163        60504 :       && integer_zerop (gimple_assign_rhs2 (g))
    5164         6485 :       && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
    5165      2100025 :       && has_single_use (gimple_assign_lhs (g)))
    5166         6188 :     return SSA_NAME_DEF_STMT (gimple_assign_rhs1 (g));
    5167              :   return g;
    5168              : }
    5169              : 
    5170              : /* Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
    5171              :    operand.  */
    5172              : 
    5173              : static bool
    5174      2094405 : uaddc_is_cplxpart (gimple *g, tree_code part)
    5175              : {
    5176      2094405 :   return (is_gimple_assign (g)
    5177      1286089 :           && gimple_assign_rhs_code (g) == part
    5178      2098153 :           && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (g), 0)) == SSA_NAME);
    5179              : }
    5180              : 
    5181              : /* Try to match e.g.
    5182              :    _29 = .ADD_OVERFLOW (_3, _4);
    5183              :    _30 = REALPART_EXPR <_29>;
    5184              :    _31 = IMAGPART_EXPR <_29>;
    5185              :    _32 = .ADD_OVERFLOW (_30, _38);
    5186              :    _33 = REALPART_EXPR <_32>;
    5187              :    _34 = IMAGPART_EXPR <_32>;
    5188              :    _35 = _31 + _34;
    5189              :    as
    5190              :    _36 = .UADDC (_3, _4, _38);
    5191              :    _33 = REALPART_EXPR <_36>;
    5192              :    _35 = IMAGPART_EXPR <_36>;
    5193              :    or
    5194              :    _22 = .SUB_OVERFLOW (_6, _5);
    5195              :    _23 = REALPART_EXPR <_22>;
    5196              :    _24 = IMAGPART_EXPR <_22>;
    5197              :    _25 = .SUB_OVERFLOW (_23, _37);
    5198              :    _26 = REALPART_EXPR <_25>;
    5199              :    _27 = IMAGPART_EXPR <_25>;
    5200              :    _28 = _24 | _27;
    5201              :    as
    5202              :    _29 = .USUBC (_6, _5, _37);
    5203              :    _26 = REALPART_EXPR <_29>;
    5204              :    _288 = IMAGPART_EXPR <_29>;
    5205              :    provided _38 or _37 above have [0, 1] range
    5206              :    and _3, _4 and _30 or _6, _5 and _23 are unsigned
    5207              :    integral types with the same precision.  Whether + or | or ^ is
    5208              :    used on the IMAGPART_EXPR results doesn't matter, with one of
    5209              :    added or subtracted operands in [0, 1] range at most one
    5210              :    .ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow.  */
    5211              : 
    5212              : static bool
    5213      2840259 : match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
    5214              : {
    5215      2840259 :   tree rhs[4];
    5216      2840259 :   rhs[0] = gimple_assign_rhs1 (stmt);
    5217      2840259 :   rhs[1] = gimple_assign_rhs2 (stmt);
    5218      2840259 :   rhs[2] = NULL_TREE;
    5219      2840259 :   rhs[3] = NULL_TREE;
    5220      2840259 :   tree type = TREE_TYPE (rhs[0]);
    5221      2840259 :   if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))
    5222              :     return false;
    5223              : 
    5224      1663108 :   auto_vec<gimple *, 2> temp_stmts;
    5225      1663108 :   if (code != BIT_IOR_EXPR && code != BIT_XOR_EXPR)
    5226              :     {
    5227              :       /* If overflow flag is ignored on the MSB limb, we can end up with
    5228              :          the most significant limb handled as r = op1 + op2 + ovf1 + ovf2;
    5229              :          or r = op1 - op2 - ovf1 - ovf2; or various equivalent expressions
    5230              :          thereof.  Handle those like the ovf = ovf1 + ovf2; case to recognize
    5231              :          the limb below the MSB, but also create another .UADDC/.USUBC call
    5232              :          for the last limb.
    5233              : 
    5234              :          First look through assignments with the same rhs code as CODE,
    5235              :          with the exception that subtraction of a constant is canonicalized
    5236              :          into addition of its negation.  rhs[0] will be minuend for
    5237              :          subtractions and one of addends for addition, all other assigned
    5238              :          rhs[i] operands will be subtrahends or other addends.  */
    5239      1534111 :       while (TREE_CODE (rhs[0]) == SSA_NAME && !rhs[3])
    5240              :         {
    5241      1509688 :           gimple *g = SSA_NAME_DEF_STMT (rhs[0]);
    5242      1509688 :           if (has_single_use (rhs[0])
    5243       505513 :               && is_gimple_assign (g)
    5244      1945723 :               && (gimple_assign_rhs_code (g) == code
    5245       403696 :                   || (code == MINUS_EXPR
    5246        51603 :                       && gimple_assign_rhs_code (g) == PLUS_EXPR
    5247        15919 :                       && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST)))
    5248              :             {
    5249        44780 :               tree r2 = gimple_assign_rhs2 (g);
    5250        44780 :               if (gimple_assign_rhs_code (g) != code)
    5251              :                 {
    5252        12441 :                   r2 = const_unop (NEGATE_EXPR, TREE_TYPE (r2), r2);
    5253        12441 :                   if (!r2)
    5254              :                     break;
    5255              :                 }
    5256        44780 :               rhs[0] = gimple_assign_rhs1 (g);
    5257        44780 :               tree &r = rhs[2] ? rhs[3] : rhs[2];
    5258        44780 :               r = r2;
    5259        44780 :               temp_stmts.quick_push (g);
    5260              :             }
    5261              :           else
    5262              :             break;
    5263              :         }
    5264      4467993 :       for (int i = 1; i <= 2; ++i)
    5265      3020327 :         while (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME && !rhs[3])
    5266              :           {
    5267       519960 :             gimple *g = SSA_NAME_DEF_STMT (rhs[i]);
    5268       519960 :             if (has_single_use (rhs[i])
    5269       258112 :                 && is_gimple_assign (g)
    5270       760308 :                 && gimple_assign_rhs_code (g) == PLUS_EXPR)
    5271              :               {
    5272        41665 :                 rhs[i] = gimple_assign_rhs1 (g);
    5273        41665 :                 if (rhs[2])
    5274         8628 :                   rhs[3] = gimple_assign_rhs2 (g);
    5275              :                 else
    5276        33037 :                   rhs[2] = gimple_assign_rhs2 (g);
    5277        41665 :                 temp_stmts.quick_push (g);
    5278              :               }
    5279              :             else
    5280              :               break;
    5281              :           }
    5282              :       /* If there are just 3 addends or one minuend and two subtrahends,
    5283              :          check for UADDC or USUBC being pattern recognized earlier.
    5284              :          Say r = op1 + op2 + ovf1 + ovf2; where the (ovf1 + ovf2) part
    5285              :          got pattern matched earlier as __imag__ .UADDC (arg1, arg2, arg3)
    5286              :          etc.  */
    5287      1489331 :       if (rhs[2] && !rhs[3])
    5288              :         {
    5289       227686 :           for (int i = (code == MINUS_EXPR ? 1 : 0); i < 3; ++i)
    5290       167388 :             if (TREE_CODE (rhs[i]) == SSA_NAME)
    5291              :               {
    5292       128638 :                 gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
    5293       128638 :                 im = uaddc_ne0 (im);
    5294       128638 :                 if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
    5295              :                   {
    5296              :                     /* We found one of the 3 addends or 2 subtrahends to be
    5297              :                        __imag__ of something, verify it is .UADDC/.USUBC.  */
    5298          236 :                     tree rhs1 = gimple_assign_rhs1 (im);
    5299          236 :                     gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
    5300          236 :                     tree ovf_lhs = NULL_TREE;
    5301          236 :                     tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
    5302          256 :                     if (gimple_call_internal_p (ovf, code == PLUS_EXPR
    5303              :                                                      ? IFN_ADD_OVERFLOW
    5304              :                                                      : IFN_SUB_OVERFLOW))
    5305              :                       {
    5306              :                         /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
    5307              :                            This is for the case of 2 chained .UADDC/.USUBC,
    5308              :                            where the first one uses 0 carry-in and the second
    5309              :                            one ignores the carry-out.
    5310              :                            So, something like:
    5311              :                            _16 = .ADD_OVERFLOW (_1, _2);
    5312              :                            _17 = REALPART_EXPR <_16>;
    5313              :                            _18 = IMAGPART_EXPR <_16>;
    5314              :                            _15 = _3 + _4;
    5315              :                            _12 = _15 + _18;
    5316              :                            where the first 3 statements come from the lower
    5317              :                            limb addition and the last 2 from the higher limb
    5318              :                            which ignores carry-out.  */
    5319          201 :                         ovf_lhs = gimple_call_lhs (ovf);
    5320          201 :                         tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
    5321          201 :                         ovf_arg1 = gimple_call_arg (ovf, 0);
    5322          201 :                         ovf_arg2 = gimple_call_arg (ovf, 1);
    5323              :                         /* In that case we need to punt if the types don't
    5324              :                            mismatch.  */
    5325          201 :                         if (!types_compatible_p (type, ovf_lhs_type)
    5326          201 :                             || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
    5327          399 :                             || !types_compatible_p (type,
    5328          198 :                                                     TREE_TYPE (ovf_arg2)))
    5329              :                           ovf_lhs = NULL_TREE;
    5330              :                         else
    5331              :                           {
    5332          498 :                             for (int i = (code == PLUS_EXPR ? 1 : 0);
    5333          498 :                                  i >= 0; --i)
    5334              :                               {
    5335          354 :                                 tree r = gimple_call_arg (ovf, i);
    5336          354 :                                 if (TREE_CODE (r) != SSA_NAME)
    5337            0 :                                   continue;
    5338          354 :                                 if (uaddc_is_cplxpart (SSA_NAME_DEF_STMT (r),
    5339              :                                                        REALPART_EXPR))
    5340              :                                   {
    5341              :                                     /* Punt if one of the args which isn't
    5342              :                                        subtracted isn't __real__; that could
    5343              :                                        then prevent better match later.
    5344              :                                        Consider:
    5345              :                                        _3 = .ADD_OVERFLOW (_1, _2);
    5346              :                                        _4 = REALPART_EXPR <_3>;
    5347              :                                        _5 = IMAGPART_EXPR <_3>;
    5348              :                                        _7 = .ADD_OVERFLOW (_4, _6);
    5349              :                                        _8 = REALPART_EXPR <_7>;
    5350              :                                        _9 = IMAGPART_EXPR <_7>;
    5351              :                                        _12 = _10 + _11;
    5352              :                                        _13 = _12 + _9;
    5353              :                                        _14 = _13 + _5;
    5354              :                                        We want to match this when called on
    5355              :                                        the last stmt as a pair of .UADDC calls,
    5356              :                                        but without this check we could turn
    5357              :                                        that prematurely on _13 = _12 + _9;
    5358              :                                        stmt into .UADDC with 0 carry-in just
    5359              :                                        on the second .ADD_OVERFLOW call and
    5360              :                                        another replacing the _12 and _13
    5361              :                                        additions.  */
    5362              :                                     ovf_lhs = NULL_TREE;
    5363              :                                     break;
    5364              :                                   }
    5365              :                               }
    5366              :                           }
    5367          194 :                         if (ovf_lhs)
    5368              :                           {
    5369          144 :                             use_operand_p use_p;
    5370          144 :                             imm_use_iterator iter;
    5371          144 :                             tree re_lhs = NULL_TREE;
    5372          432 :                             FOR_EACH_IMM_USE_FAST (use_p, iter, ovf_lhs)
    5373              :                               {
    5374          288 :                                 gimple *use_stmt = USE_STMT (use_p);
    5375          288 :                                 if (is_gimple_debug (use_stmt))
    5376            0 :                                   continue;
    5377          288 :                                 if (use_stmt == im)
    5378          144 :                                   continue;
    5379          144 :                                 if (!uaddc_is_cplxpart (use_stmt,
    5380              :                                                         REALPART_EXPR))
    5381              :                                   {
    5382              :                                     ovf_lhs = NULL_TREE;
    5383              :                                     break;
    5384              :                                   }
    5385          144 :                                 re_lhs = gimple_assign_lhs (use_stmt);
    5386          144 :                               }
    5387          144 :                             if (ovf_lhs && re_lhs)
    5388              :                               {
    5389          388 :                                 FOR_EACH_IMM_USE_FAST (use_p, iter, re_lhs)
    5390              :                                   {
    5391          300 :                                     gimple *use_stmt = USE_STMT (use_p);
    5392          300 :                                     if (is_gimple_debug (use_stmt))
    5393          109 :                                       continue;
    5394          191 :                                     internal_fn ifn
    5395          191 :                                       = gimple_call_internal_fn (ovf);
    5396              :                                     /* Punt if the __real__ of lhs is used
    5397              :                                        in the same .*_OVERFLOW call.
    5398              :                                        Consider:
    5399              :                                        _3 = .ADD_OVERFLOW (_1, _2);
    5400              :                                        _4 = REALPART_EXPR <_3>;
    5401              :                                        _5 = IMAGPART_EXPR <_3>;
    5402              :                                        _7 = .ADD_OVERFLOW (_4, _6);
    5403              :                                        _8 = REALPART_EXPR <_7>;
    5404              :                                        _9 = IMAGPART_EXPR <_7>;
    5405              :                                        _12 = _10 + _11;
    5406              :                                        _13 = _12 + _5;
    5407              :                                        _14 = _13 + _9;
    5408              :                                        We want to match this when called on
    5409              :                                        the last stmt as a pair of .UADDC calls,
    5410              :                                        but without this check we could turn
    5411              :                                        that prematurely on _13 = _12 + _5;
    5412              :                                        stmt into .UADDC with 0 carry-in just
    5413              :                                        on the first .ADD_OVERFLOW call and
    5414              :                                        another replacing the _12 and _13
    5415              :                                        additions.  */
    5416          191 :                                     if (gimple_call_internal_p (use_stmt, ifn))
    5417              :                                       {
    5418              :                                         ovf_lhs = NULL_TREE;
    5419              :                                         break;
    5420              :                                       }
    5421          144 :                                   }
    5422              :                               }
    5423              :                           }
    5424              :                       }
    5425          144 :                     if ((ovf_lhs
    5426          157 :                          || gimple_call_internal_p (ovf,
    5427              :                                                     code == PLUS_EXPR
    5428              :                                                     ? IFN_UADDC : IFN_USUBC))
    5429          252 :                         && (optab_handler (code == PLUS_EXPR
    5430              :                                            ? uaddc5_optab : usubc5_optab,
    5431           94 :                                            TYPE_MODE (type))
    5432              :                             != CODE_FOR_nothing))
    5433              :                       {
    5434              :                         /* And in that case build another .UADDC/.USUBC
    5435              :                            call for the most significand limb addition.
    5436              :                            Overflow bit is ignored here.  */
    5437           63 :                         if (i != 2)
    5438           63 :                           std::swap (rhs[i], rhs[2]);
    5439           63 :                         gimple *g
    5440           77 :                           = gimple_build_call_internal (code == PLUS_EXPR
    5441              :                                                         ? IFN_UADDC
    5442              :                                                         : IFN_USUBC,
    5443              :                                                         3, rhs[0], rhs[1],
    5444              :                                                         rhs[2]);
    5445           63 :                         tree nlhs = make_ssa_name (build_complex_type (type));
    5446           63 :                         gimple_call_set_lhs (g, nlhs);
    5447           63 :                         gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5448           63 :                         tree ilhs = gimple_assign_lhs (stmt);
    5449           63 :                         g = gimple_build_assign (ilhs, REALPART_EXPR,
    5450              :                                                  build1 (REALPART_EXPR,
    5451           63 :                                                          TREE_TYPE (ilhs),
    5452              :                                                          nlhs));
    5453           63 :                         gsi_replace (gsi, g, true);
    5454              :                         /* And if it is initialized from result of __imag__
    5455              :                            of .{ADD,SUB}_OVERFLOW call, replace that
    5456              :                            call with .U{ADD,SUB}C call with the same arguments,
    5457              :                            just 0 added as third argument.  This isn't strictly
    5458              :                            necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
    5459              :                            produce the same result, but may result in better
    5460              :                            generated code on some targets where the backend can
    5461              :                            better prepare in how the result will be used.  */
    5462           63 :                         if (ovf_lhs)
    5463              :                           {
    5464           57 :                             tree zero = build_zero_cst (type);
    5465           57 :                             g = gimple_build_call_internal (code == PLUS_EXPR
    5466              :                                                             ? IFN_UADDC
    5467              :                                                             : IFN_USUBC,
    5468              :                                                             3, ovf_arg1,
    5469              :                                                             ovf_arg2, zero);
    5470           57 :                             gimple_call_set_lhs (g, ovf_lhs);
    5471           57 :                             gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf);
    5472           57 :                             gsi_replace (&gsi2, g, true);
    5473              :                           }
    5474              :                         return true;
    5475              :                       }
    5476              :                   }
    5477              :               }
    5478              :           return false;
    5479              :         }
    5480      1428970 :       if (code == MINUS_EXPR && !rhs[2])
    5481              :         return false;
    5482          177 :       if (code == MINUS_EXPR)
    5483              :         /* Code below expects rhs[0] and rhs[1] to have the IMAGPART_EXPRs.
    5484              :            So, for MINUS_EXPR swap the single added rhs operand (others are
    5485              :            subtracted) to rhs[3].  */
    5486          177 :         std::swap (rhs[0], rhs[3]);
    5487              :     }
    5488              :   /* Walk from both operands of STMT (for +/- even sometimes from
    5489              :      all the 4 addends or 3 subtrahends), see through casts and != 0
    5490              :      statements which would preserve [0, 1] range of values and
    5491              :      check which is initialized from __imag__.  */
    5492      1495127 :   gimple *im1 = NULL, *im2 = NULL;
    5493     14947934 :   for (int i = 0; i < (code == MINUS_EXPR ? 3 : 4); i++)
    5494      5979582 :     if (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME)
    5495              :       {
    5496      1964662 :         gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
    5497      1964662 :         im = uaddc_ne0 (im);
    5498      1964662 :         if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
    5499              :           {
    5500         2986 :             if (im1 == NULL)
    5501              :               {
    5502         2597 :                 im1 = im;
    5503         2597 :                 if (i != 0)
    5504          909 :                   std::swap (rhs[0], rhs[i]);
    5505              :               }
    5506              :             else
    5507              :               {
    5508          389 :                 im2 = im;
    5509          389 :                 if (i != 1)
    5510           22 :                   std::swap (rhs[1], rhs[i]);
    5511              :                 break;
    5512              :               }
    5513              :           }
    5514              :       }
    5515              :   /* If we don't find at least two, punt.  */
    5516      1495127 :   if (!im2)
    5517              :     return false;
    5518              :   /* Check they are __imag__ of .ADD_OVERFLOW or .SUB_OVERFLOW call results,
    5519              :      either both .ADD_OVERFLOW or both .SUB_OVERFLOW and that we have
    5520              :      uaddc5/usubc5 named pattern for the corresponding mode.  */
    5521          389 :   gimple *ovf1
    5522          389 :     = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im1), 0));
    5523          389 :   gimple *ovf2
    5524          389 :     = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im2), 0));
    5525          389 :   internal_fn ifn;
    5526          389 :   if (!is_gimple_call (ovf1)
    5527          389 :       || !gimple_call_internal_p (ovf1)
    5528          389 :       || ((ifn = gimple_call_internal_fn (ovf1)) != IFN_ADD_OVERFLOW
    5529           61 :           && ifn != IFN_SUB_OVERFLOW)
    5530          366 :       || !gimple_call_internal_p (ovf2, ifn)
    5531          396 :       || optab_handler (ifn == IFN_ADD_OVERFLOW ? uaddc5_optab : usubc5_optab,
    5532          362 :                         TYPE_MODE (type)) == CODE_FOR_nothing
    5533           95 :       || (rhs[2]
    5534           17 :           && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
    5535           15 :                             TYPE_MODE (type)) == CODE_FOR_nothing)
    5536           95 :       || !types_compatible_p (type,
    5537           95 :                               TREE_TYPE (TREE_TYPE (gimple_call_lhs (ovf1))))
    5538          483 :       || !types_compatible_p (type,
    5539           94 :                               TREE_TYPE (TREE_TYPE (gimple_call_lhs (ovf2)))))
    5540              :     return false;
    5541           94 :   tree arg1, arg2, arg3 = NULL_TREE;
    5542           94 :   gimple *re1 = NULL, *re2 = NULL;
    5543              :   /* On one of the two calls, one of the .ADD_OVERFLOW/.SUB_OVERFLOW arguments
    5544              :      should be initialized from __real__ of the other of the two calls.
    5545              :      Though, for .SUB_OVERFLOW, it has to be the first argument, not the
    5546              :      second one.  */
    5547          249 :   for (int i = (ifn == IFN_ADD_OVERFLOW ? 1 : 0); i >= 0; --i)
    5548          351 :     for (gimple *ovf = ovf1; ovf; ovf = (ovf == ovf1 ? ovf2 : NULL))
    5549              :       {
    5550          290 :         tree arg = gimple_call_arg (ovf, i);
    5551          290 :         if (TREE_CODE (arg) != SSA_NAME)
    5552            2 :           continue;
    5553          288 :         re1 = SSA_NAME_DEF_STMT (arg);
    5554          288 :         if (uaddc_is_cplxpart (re1, REALPART_EXPR)
    5555          382 :             && (SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (re1), 0))
    5556           94 :                 == (ovf == ovf1 ? ovf2 : ovf1)))
    5557              :           {
    5558           94 :             if (ovf == ovf1)
    5559              :               {
    5560              :                 /* Make sure ovf2 is the .*_OVERFLOW call with argument
    5561              :                    initialized from __real__ of ovf1.  */
    5562           20 :                 std::swap (rhs[0], rhs[1]);
    5563           20 :                 std::swap (im1, im2);
    5564           20 :                 std::swap (ovf1, ovf2);
    5565              :               }
    5566           94 :             arg3 = gimple_call_arg (ovf, 1 - i);
    5567           94 :             i = -1;
    5568           94 :             break;
    5569              :           }
    5570              :       }
    5571           94 :   if (!arg3)
    5572              :     return false;
    5573           94 :   arg1 = gimple_call_arg (ovf1, 0);
    5574           94 :   arg2 = gimple_call_arg (ovf1, 1);
    5575           94 :   if (!types_compatible_p (type, TREE_TYPE (arg1)))
    5576              :     return false;
    5577           94 :   int kind[2] = { 0, 0 };
    5578           94 :   tree arg_im[2] = { NULL_TREE, NULL_TREE };
    5579              :   /* At least one of arg2 and arg3 should have type compatible
    5580              :      with arg1/rhs[0], and the other one should have value in [0, 1]
    5581              :      range.  If both are in [0, 1] range and type compatible with
    5582              :      arg1/rhs[0], try harder to find after looking through casts,
    5583              :      != 0 comparisons which one is initialized to __imag__ of
    5584              :      .{ADD,SUB}_OVERFLOW or .U{ADD,SUB}C call results.  */
    5585          282 :   for (int i = 0; i < 2; ++i)
    5586              :     {
    5587          188 :       tree arg = i == 0 ? arg2 : arg3;
    5588          188 :       if (types_compatible_p (type, TREE_TYPE (arg)))
    5589          163 :         kind[i] = 1;
    5590          376 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (arg))
    5591          376 :           || (TYPE_PRECISION (TREE_TYPE (arg)) == 1
    5592           25 :               && !TYPE_UNSIGNED (TREE_TYPE (arg))))
    5593            0 :         continue;
    5594          188 :       if (tree_zero_one_valued_p (arg))
    5595           52 :         kind[i] |= 2;
    5596          188 :       if (TREE_CODE (arg) == SSA_NAME)
    5597              :         {
    5598          185 :           gimple *g = SSA_NAME_DEF_STMT (arg);
    5599          185 :           if (gimple_assign_cast_p (g))
    5600              :             {
    5601           30 :               tree op = gimple_assign_rhs1 (g);
    5602           30 :               if (TREE_CODE (op) == SSA_NAME
    5603           30 :                   && INTEGRAL_TYPE_P (TREE_TYPE (op)))
    5604           30 :                 g = SSA_NAME_DEF_STMT (op);
    5605              :             }
    5606          185 :           g = uaddc_ne0 (g);
    5607          185 :           if (!uaddc_is_cplxpart (g, IMAGPART_EXPR))
    5608          125 :             continue;
    5609           60 :           arg_im[i] = gimple_assign_lhs (g);
    5610           60 :           g = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (g), 0));
    5611           60 :           if (!is_gimple_call (g) || !gimple_call_internal_p (g))
    5612            0 :             continue;
    5613           60 :           switch (gimple_call_internal_fn (g))
    5614              :             {
    5615           60 :             case IFN_ADD_OVERFLOW:
    5616           60 :             case IFN_SUB_OVERFLOW:
    5617           60 :             case IFN_UADDC:
    5618           60 :             case IFN_USUBC:
    5619           60 :               break;
    5620            0 :             default:
    5621            0 :               continue;
    5622              :             }
    5623           60 :           kind[i] |= 4;
    5624              :         }
    5625              :     }
    5626              :   /* Make arg2 the one with compatible type and arg3 the one
    5627              :      with [0, 1] range.  If both is true for both operands,
    5628              :      prefer as arg3 result of __imag__ of some ifn.  */
    5629           94 :   if ((kind[0] & 1) == 0 || ((kind[1] & 1) != 0 && kind[0] > kind[1]))
    5630              :     {
    5631            1 :       std::swap (arg2, arg3);
    5632            1 :       std::swap (kind[0], kind[1]);
    5633            1 :       std::swap (arg_im[0], arg_im[1]);
    5634              :     }
    5635           94 :   if ((kind[0] & 1) == 0 || (kind[1] & 6) == 0)
    5636              :     return false;
    5637           70 :   if (!has_single_use (gimple_assign_lhs (im1))
    5638           68 :       || !has_single_use (gimple_assign_lhs (im2))
    5639           68 :       || !has_single_use (gimple_assign_lhs (re1))
    5640          138 :       || num_imm_uses (gimple_call_lhs (ovf1)) != 2)
    5641              :     return false;
    5642              :   /* Check that ovf2's result is used in __real__ and set re2
    5643              :      to that statement.  */
    5644           68 :   use_operand_p use_p;
    5645           68 :   imm_use_iterator iter;
    5646           68 :   tree lhs = gimple_call_lhs (ovf2);
    5647          203 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    5648              :     {
    5649          135 :       gimple *use_stmt = USE_STMT (use_p);
    5650          135 :       if (is_gimple_debug (use_stmt))
    5651            0 :         continue;
    5652          135 :       if (use_stmt == im2)
    5653           68 :         continue;
    5654           67 :       if (re2)
    5655              :         return false;
    5656           67 :       if (!uaddc_is_cplxpart (use_stmt, REALPART_EXPR))
    5657              :         return false;
    5658              :       re2 = use_stmt;
    5659            0 :     }
    5660              :   /* Build .UADDC/.USUBC call which will be placed before the stmt.  */
    5661           68 :   gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf2);
    5662           68 :   gimple *g;
    5663           68 :   if ((kind[1] & 4) != 0 && types_compatible_p (type, TREE_TYPE (arg_im[1])))
    5664              :     arg3 = arg_im[1];
    5665           68 :   if ((kind[1] & 1) == 0)
    5666              :     {
    5667           25 :       if (TREE_CODE (arg3) == INTEGER_CST)
    5668            0 :         arg3 = fold_convert (type, arg3);
    5669              :       else
    5670              :         {
    5671           25 :           g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, arg3);
    5672           25 :           gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
    5673           25 :           arg3 = gimple_assign_lhs (g);
    5674              :         }
    5675              :     }
    5676           91 :   g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
    5677              :                                   ? IFN_UADDC : IFN_USUBC,
    5678              :                                   3, arg1, arg2, arg3);
    5679           68 :   tree nlhs = make_ssa_name (TREE_TYPE (lhs));
    5680           68 :   gimple_call_set_lhs (g, nlhs);
    5681           68 :   gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
    5682              :   /* In the case where stmt is | or ^ of two overflow flags
    5683              :      or addition of those, replace stmt with __imag__ of the above
    5684              :      added call.  In case of arg1 + arg2 + (ovf1 + ovf2) or
    5685              :      arg1 - arg2 - (ovf1 + ovf2) just emit it before stmt.  */
    5686           68 :   tree ilhs = rhs[2] ? make_ssa_name (type) : gimple_assign_lhs (stmt);
    5687           68 :   g = gimple_build_assign (ilhs, IMAGPART_EXPR,
    5688           68 :                            build1 (IMAGPART_EXPR, TREE_TYPE (ilhs), nlhs));
    5689           68 :   if (rhs[2])
    5690              :     {
    5691           15 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5692              :       /* Remove some further statements which can't be kept in the IL because
    5693              :          they can use SSA_NAMEs whose setter is going to be removed too.  */
    5694           75 :       for (gimple *g2 : temp_stmts)
    5695              :         {
    5696           30 :           gsi2 = gsi_for_stmt (g2);
    5697           30 :           gsi_remove (&gsi2, true);
    5698           30 :           release_defs (g2);
    5699              :         }
    5700              :     }
    5701              :   else
    5702           53 :     gsi_replace (gsi, g, true);
    5703              :   /* Remove some statements which can't be kept in the IL because they
    5704              :      use SSA_NAME whose setter is going to be removed too.  */
    5705           68 :   tree rhs1 = rhs[1];
    5706          104 :   for (int i = 0; i < 2; i++)
    5707           86 :     if (rhs1 == gimple_assign_lhs (im2))
    5708              :       break;
    5709              :     else
    5710              :       {
    5711           36 :         g = SSA_NAME_DEF_STMT (rhs1);
    5712           36 :         rhs1 = gimple_assign_rhs1 (g);
    5713           36 :         gsi2 = gsi_for_stmt (g);
    5714           36 :         gsi_remove (&gsi2, true);
    5715           36 :         release_defs (g);
    5716              :       }
    5717           68 :   gcc_checking_assert (rhs1 == gimple_assign_lhs (im2));
    5718           68 :   gsi2 = gsi_for_stmt (im2);
    5719           68 :   gsi_remove (&gsi2, true);
    5720           68 :   release_defs (im2);
    5721              :   /* Replace the re2 statement with __real__ of the newly added
    5722              :      .UADDC/.USUBC call.  */
    5723           68 :   if (re2)
    5724              :     {
    5725           67 :       gsi2 = gsi_for_stmt (re2);
    5726           67 :       tree rlhs = gimple_assign_lhs (re2);
    5727           67 :       g = gimple_build_assign (rlhs, REALPART_EXPR,
    5728           67 :                                build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
    5729           67 :       gsi_replace (&gsi2, g, true);
    5730              :     }
    5731           68 :   if (rhs[2])
    5732              :     {
    5733              :       /* If this is the arg1 + arg2 + (ovf1 + ovf2) or
    5734              :          arg1 - arg2 - (ovf1 + ovf2) case for the most significant limb,
    5735              :          replace stmt with __real__ of another .UADDC/.USUBC call which
    5736              :          handles the most significant limb.  Overflow flag from this is
    5737              :          ignored.  */
    5738           17 :       g = gimple_build_call_internal (code == PLUS_EXPR
    5739              :                                       ? IFN_UADDC : IFN_USUBC,
    5740              :                                       3, rhs[3], rhs[2], ilhs);
    5741           15 :       nlhs = make_ssa_name (TREE_TYPE (lhs));
    5742           15 :       gimple_call_set_lhs (g, nlhs);
    5743           15 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5744           15 :       ilhs = gimple_assign_lhs (stmt);
    5745           15 :       g = gimple_build_assign (ilhs, REALPART_EXPR,
    5746           15 :                                build1 (REALPART_EXPR, TREE_TYPE (ilhs), nlhs));
    5747           15 :       gsi_replace (gsi, g, true);
    5748              :     }
    5749           68 :   if (TREE_CODE (arg3) == SSA_NAME)
    5750              :     {
    5751              :       /* When pattern recognizing the second least significant limb
    5752              :          above (i.e. first pair of .{ADD,SUB}_OVERFLOW calls for one limb),
    5753              :          check if the [0, 1] range argument (i.e. carry in) isn't the
    5754              :          result of another .{ADD,SUB}_OVERFLOW call (one handling the
    5755              :          least significant limb).  Again look through casts and != 0.  */
    5756           67 :       gimple *im3 = SSA_NAME_DEF_STMT (arg3);
    5757           92 :       for (int i = 0; i < 2; ++i)
    5758              :         {
    5759           92 :           gimple *im4 = uaddc_cast (im3);
    5760           92 :           if (im4 == im3)
    5761              :             break;
    5762              :           else
    5763           25 :             im3 = im4;
    5764              :         }
    5765           67 :       im3 = uaddc_ne0 (im3);
    5766           67 :       if (uaddc_is_cplxpart (im3, IMAGPART_EXPR))
    5767              :         {
    5768           60 :           gimple *ovf3
    5769           60 :             = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
    5770           60 :           if (gimple_call_internal_p (ovf3, ifn))
    5771              :             {
    5772           25 :               lhs = gimple_call_lhs (ovf3);
    5773           25 :               arg1 = gimple_call_arg (ovf3, 0);
    5774           25 :               arg2 = gimple_call_arg (ovf3, 1);
    5775           25 :               if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
    5776           25 :                   && types_compatible_p (type, TREE_TYPE (arg1))
    5777           50 :                   && types_compatible_p (type, TREE_TYPE (arg2)))
    5778              :                 {
    5779              :                   /* And if it is initialized from result of __imag__
    5780              :                      of .{ADD,SUB}_OVERFLOW call, replace that
    5781              :                      call with .U{ADD,SUB}C call with the same arguments,
    5782              :                      just 0 added as third argument.  This isn't strictly
    5783              :                      necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
    5784              :                      produce the same result, but may result in better
    5785              :                      generated code on some targets where the backend can
    5786              :                      better prepare in how the result will be used.  */
    5787           25 :                   g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
    5788              :                                                   ? IFN_UADDC : IFN_USUBC,
    5789              :                                                   3, arg1, arg2,
    5790              :                                                   build_zero_cst (type));
    5791           25 :                   gimple_call_set_lhs (g, lhs);
    5792           25 :                   gsi2 = gsi_for_stmt (ovf3);
    5793           25 :                   gsi_replace (&gsi2, g, true);
    5794              :                 }
    5795              :             }
    5796              :         }
    5797              :     }
    5798              :   return true;
    5799      1663108 : }
    5800              : 
    5801              : /* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
    5802              :    (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
    5803              :    isn't a direct optab.  Also handle `<=`/`>` to be
    5804              :    `x & (x - 1) !=/== x`. */
    5805              : 
    5806              : static void
    5807      4546610 : match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
    5808              : {
    5809      4546610 :   tree clhs, crhs;
    5810      4546610 :   enum tree_code code;
    5811      4546610 :   bool was_le = false;
    5812      4546610 :   if (gimple_code (stmt) == GIMPLE_COND)
    5813              :     {
    5814      4219657 :       clhs = gimple_cond_lhs (stmt);
    5815      4219657 :       crhs = gimple_cond_rhs (stmt);
    5816      4219657 :       code = gimple_cond_code (stmt);
    5817              :     }
    5818              :   else
    5819              :     {
    5820       326953 :       clhs = gimple_assign_rhs1 (stmt);
    5821       326953 :       crhs = gimple_assign_rhs2 (stmt);
    5822       326953 :       code = gimple_assign_rhs_code (stmt);
    5823              :     }
    5824      4546610 :   if (code != LE_EXPR && code != GT_EXPR
    5825      4546610 :       && code != EQ_EXPR && code != NE_EXPR)
    5826      4546568 :     return;
    5827      2134790 :   if (code == LE_EXPR || code == GT_EXPR)
    5828      4286129 :     was_le = true;
    5829      4286129 :   if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
    5830              :     return;
    5831       163459 :   gimple *call = SSA_NAME_DEF_STMT (clhs);
    5832       163459 :   combined_fn cfn = gimple_call_combined_fn (call);
    5833       163459 :   switch (cfn)
    5834              :     {
    5835           51 :     CASE_CFN_POPCOUNT:
    5836           51 :       break;
    5837              :     default:
    5838              :       return;
    5839              :     }
    5840           51 :   if (!has_single_use (clhs))
    5841              :     return;
    5842           50 :   tree arg = gimple_call_arg (call, 0);
    5843           50 :   tree type = TREE_TYPE (arg);
    5844           50 :   if (!INTEGRAL_TYPE_P (type))
    5845              :     return;
    5846           50 :   bool nonzero_arg = tree_expr_nonzero_p (arg);
    5847           50 :   if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
    5848              :     {
    5849              :       /* Tell expand_POPCOUNT the popcount result is only used in equality
    5850              :          comparison with one, so that it can decide based on rtx costs.  */
    5851           16 :       gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
    5852              :                                               was_le ? integer_minus_one_node
    5853            8 :                                               : (nonzero_arg ? integer_zero_node
    5854              :                                                  : integer_one_node));
    5855            8 :       gimple_call_set_lhs (g, gimple_call_lhs (call));
    5856            8 :       gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    5857            8 :       gsi_replace (&gsi2, g, true);
    5858            8 :       return;
    5859              :     }
    5860           42 :   tree argm1 = make_ssa_name (type);
    5861           42 :   gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
    5862              :                                    build_int_cst (type, -1));
    5863           42 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5864           42 :   g = gimple_build_assign (make_ssa_name (type),
    5865           42 :                            (nonzero_arg || was_le) ? BIT_AND_EXPR : BIT_XOR_EXPR,
    5866              :                            arg, argm1);
    5867           42 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    5868           42 :   tree_code cmpcode;
    5869           42 :   if (was_le)
    5870              :     {
    5871            0 :       argm1 = build_zero_cst (type);
    5872            0 :       cmpcode = code == LE_EXPR ? EQ_EXPR : NE_EXPR;
    5873              :     }
    5874           42 :   else if (nonzero_arg)
    5875              :     {
    5876            2 :       argm1 = build_zero_cst (type);
    5877            2 :       cmpcode = code;
    5878              :     }
    5879              :   else
    5880           40 :     cmpcode = code == EQ_EXPR ? GT_EXPR : LE_EXPR;
    5881           42 :   if (gcond *cond = dyn_cast <gcond *> (stmt))
    5882              :     {
    5883            2 :       gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
    5884            2 :       gimple_cond_set_rhs (cond, argm1);
    5885            2 :       gimple_cond_set_code (cond, cmpcode);
    5886              :     }
    5887              :   else
    5888              :     {
    5889           40 :       gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
    5890           40 :       gimple_assign_set_rhs2 (stmt, argm1);
    5891           40 :       gimple_assign_set_rhs_code (stmt, cmpcode);
    5892              :     }
    5893           42 :   update_stmt (stmt);
    5894           42 :   gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
    5895           42 :   gsi_remove (&gsi2, true);
    5896           42 :   release_defs (call);
    5897              : }
    5898              : 
    5899              : /* Return true if target has support for divmod.  */
    5900              : 
    5901              : static bool
    5902        38380 : target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
    5903              : {
    5904              :   /* If target supports hardware divmod insn, use it for divmod.  */
    5905        38380 :   if (optab_handler (divmod_optab, mode) != CODE_FOR_nothing)
    5906              :     return true;
    5907              : 
    5908              :   /* Check if libfunc for divmod is available.  */
    5909         2580 :   rtx libfunc = optab_libfunc (divmod_optab, mode);
    5910         2580 :   if (libfunc != NULL_RTX)
    5911              :     {
    5912              :       /* If optab_handler exists for div_optab, perhaps in a wider mode,
    5913              :          we don't want to use the libfunc even if it exists for given mode.  */
    5914              :       machine_mode div_mode;
    5915        10754 :       FOR_EACH_MODE_FROM (div_mode, mode)
    5916         8174 :         if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
    5917              :           return false;
    5918              : 
    5919         2580 :       return targetm.expand_divmod_libfunc != NULL;
    5920              :     }
    5921              : 
    5922              :   return false;
    5923              : }
    5924              : 
    5925              : /* Check if stmt is candidate for divmod transform.  */
    5926              : 
    5927              : static bool
    5928        57127 : divmod_candidate_p (gassign *stmt)
    5929              : {
    5930        57127 :   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
    5931        57127 :   machine_mode mode = TYPE_MODE (type);
    5932        57127 :   optab divmod_optab, div_optab;
    5933              : 
    5934        57127 :   if (TYPE_UNSIGNED (type))
    5935              :     {
    5936              :       divmod_optab = udivmod_optab;
    5937              :       div_optab = udiv_optab;
    5938              :     }
    5939              :   else
    5940              :     {
    5941        28390 :       divmod_optab = sdivmod_optab;
    5942        28390 :       div_optab = sdiv_optab;
    5943              :     }
    5944              : 
    5945        57127 :   tree op1 = gimple_assign_rhs1 (stmt);
    5946        57127 :   tree op2 = gimple_assign_rhs2 (stmt);
    5947              : 
    5948              :   /* Disable the transform if either is a constant, since division-by-constant
    5949              :      may have specialized expansion.  */
    5950        57127 :   if (CONSTANT_CLASS_P (op1))
    5951              :     return false;
    5952              : 
    5953        53178 :   if (CONSTANT_CLASS_P (op2))
    5954              :     {
    5955        17037 :       if (integer_pow2p (op2))
    5956              :         return false;
    5957              : 
    5958        14910 :       if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
    5959        15991 :           && element_precision (type) <= BITS_PER_WORD)
    5960              :         return false;
    5961              : 
    5962              :       /* If the divisor is not power of 2 and the precision wider than
    5963              :          HWI, expand_divmod punts on that, so in that case it is better
    5964              :          to use divmod optab or libfunc.  Similarly if choose_multiplier
    5965              :          might need pre/post shifts of BITS_PER_WORD or more.  */
    5966              :     }
    5967              : 
    5968              :   /* Exclude the case where TYPE_OVERFLOW_TRAPS (type) as that should
    5969              :      expand using the [su]divv optabs.  */
    5970        38380 :   if (TYPE_OVERFLOW_TRAPS (type))
    5971              :     return false;
    5972              : 
    5973        38380 :   if (!target_supports_divmod_p (divmod_optab, div_optab, mode))
    5974              :     return false;
    5975              : 
    5976              :   return true;
    5977              : }
    5978              : 
    5979              : /* This function looks for:
    5980              :    t1 = a TRUNC_DIV_EXPR b;
    5981              :    t2 = a TRUNC_MOD_EXPR b;
    5982              :    and transforms it to the following sequence:
    5983              :    complex_tmp = DIVMOD (a, b);
    5984              :    t1 = REALPART_EXPR(a);
    5985              :    t2 = IMAGPART_EXPR(b);
    5986              :    For conditions enabling the transform see divmod_candidate_p().
    5987              : 
    5988              :    The pass has three parts:
    5989              :    1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
    5990              :       other trunc_div_expr and trunc_mod_expr stmts.
    5991              :    2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
    5992              :       to stmts vector.
    5993              :    3) Insert DIVMOD call just before top_stmt and update entries in
    5994              :       stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
    5995              :       IMAGPART_EXPR for mod).  */
    5996              : 
    5997              : static bool
    5998        57146 : convert_to_divmod (gassign *stmt)
    5999              : {
    6000        57146 :   if (stmt_can_throw_internal (cfun, stmt)
    6001        57146 :       || !divmod_candidate_p (stmt))
    6002              :     return false;
    6003              : 
    6004        38380 :   tree op1 = gimple_assign_rhs1 (stmt);
    6005        38380 :   tree op2 = gimple_assign_rhs2 (stmt);
    6006              : 
    6007        38380 :   imm_use_iterator use_iter;
    6008        38380 :   gimple *use_stmt;
    6009        38380 :   auto_vec<gimple *> stmts;
    6010              : 
    6011        38380 :   gimple *top_stmt = stmt;
    6012        38380 :   basic_block top_bb = gimple_bb (stmt);
    6013              : 
    6014              :   /* Part 1: Try to set top_stmt to "topmost" stmt that dominates
    6015              :      at-least stmt and possibly other trunc_div/trunc_mod stmts
    6016              :      having same operands as stmt.  */
    6017              : 
    6018       326672 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op1)
    6019              :     {
    6020       288292 :       if (is_gimple_assign (use_stmt)
    6021       238013 :           && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
    6022       226245 :               || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
    6023       215602 :           && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0)
    6024       503777 :           && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0))
    6025              :         {
    6026        50038 :           if (stmt_can_throw_internal (cfun, use_stmt))
    6027            0 :             continue;
    6028              : 
    6029        50038 :           basic_block bb = gimple_bb (use_stmt);
    6030              : 
    6031        50038 :           if (bb == top_bb)
    6032              :             {
    6033        49307 :               if (gimple_uid (use_stmt) < gimple_uid (top_stmt))
    6034         5153 :                 top_stmt = use_stmt;
    6035              :             }
    6036          731 :           else if (dominated_by_p (CDI_DOMINATORS, top_bb, bb))
    6037              :             {
    6038          194 :               top_bb = bb;
    6039          194 :               top_stmt = use_stmt;
    6040              :             }
    6041              :         }
    6042        38380 :     }
    6043              : 
    6044        38380 :   tree top_op1 = gimple_assign_rhs1 (top_stmt);
    6045        38380 :   tree top_op2 = gimple_assign_rhs2 (top_stmt);
    6046              : 
    6047        38380 :   stmts.safe_push (top_stmt);
    6048        38380 :   bool div_seen = (gimple_assign_rhs_code (top_stmt) == TRUNC_DIV_EXPR);
    6049              : 
    6050              :   /* Part 2: Add all trunc_div/trunc_mod statements domianted by top_bb
    6051              :      to stmts vector. The 2nd loop will always add stmt to stmts vector, since
    6052              :      gimple_bb (top_stmt) dominates gimple_bb (stmt), so the
    6053              :      2nd loop ends up adding at-least single trunc_mod_expr stmt.  */
    6054              : 
    6055       326672 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, top_op1)
    6056              :     {
    6057       288292 :       if (is_gimple_assign (use_stmt)
    6058       238013 :           && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
    6059       226245 :               || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
    6060       215602 :           && operand_equal_p (top_op1, gimple_assign_rhs1 (use_stmt), 0)
    6061       503777 :           && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0))
    6062              :         {
    6063        88508 :           if (use_stmt == top_stmt
    6064        11658 :               || stmt_can_throw_internal (cfun, use_stmt)
    6065        61696 :               || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb))
    6066        38470 :             continue;
    6067              : 
    6068        11568 :           stmts.safe_push (use_stmt);
    6069        11568 :           if (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR)
    6070       288292 :             div_seen = true;
    6071              :         }
    6072        38380 :     }
    6073              : 
    6074        38380 :   if (!div_seen)
    6075              :     return false;
    6076              : 
    6077              :   /* Part 3: Create libcall to internal fn DIVMOD:
    6078              :      divmod_tmp = DIVMOD (op1, op2).  */
    6079              : 
    6080        11541 :   gcall *call_stmt = gimple_build_call_internal (IFN_DIVMOD, 2, op1, op2);
    6081        11541 :   tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
    6082              :                                  call_stmt, "divmod_tmp");
    6083        11541 :   gimple_call_set_lhs (call_stmt, res);
    6084              :   /* We rejected throwing statements above.  */
    6085        11541 :   gimple_call_set_nothrow (call_stmt, true);
    6086              : 
    6087              :   /* Insert the call before top_stmt.  */
    6088        11541 :   gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
    6089        11541 :   gsi_insert_before (&top_stmt_gsi, call_stmt, GSI_SAME_STMT);
    6090              : 
    6091        11541 :   widen_mul_stats.divmod_calls_inserted++;
    6092              : 
    6093              :   /* Update all statements in stmts vector:
    6094              :      lhs = op1 TRUNC_DIV_EXPR op2 -> lhs = REALPART_EXPR<divmod_tmp>
    6095              :      lhs = op1 TRUNC_MOD_EXPR op2 -> lhs = IMAGPART_EXPR<divmod_tmp>.  */
    6096              : 
    6097        73028 :   for (unsigned i = 0; stmts.iterate (i, &use_stmt); ++i)
    6098              :     {
    6099        23107 :       tree new_rhs;
    6100              : 
    6101        23107 :       switch (gimple_assign_rhs_code (use_stmt))
    6102              :         {
    6103        11551 :           case TRUNC_DIV_EXPR:
    6104        11551 :             new_rhs = fold_build1 (REALPART_EXPR, TREE_TYPE (op1), res);
    6105        11551 :             break;
    6106              : 
    6107        11556 :           case TRUNC_MOD_EXPR:
    6108        11556 :             new_rhs = fold_build1 (IMAGPART_EXPR, TREE_TYPE (op1), res);
    6109        11556 :             break;
    6110              : 
    6111            0 :           default:
    6112            0 :             gcc_unreachable ();
    6113              :         }
    6114              : 
    6115        23107 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    6116        23107 :       gimple_assign_set_rhs_from_tree (&gsi, new_rhs);
    6117        23107 :       update_stmt (use_stmt);
    6118              :     }
    6119              : 
    6120              :   return true;
    6121        38380 : }
    6122              : 
    6123              : /* Process a single gimple assignment STMT, which has a RSHIFT_EXPR as
    6124              :    its rhs, and try to convert it into a MULT_HIGHPART_EXPR.  The return
    6125              :    value is true iff we converted the statement.  */
    6126              : 
    6127              : static bool
    6128       173600 : convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
    6129              : {
    6130       173600 :   tree lhs = gimple_assign_lhs (stmt);
    6131       173600 :   tree stype = TREE_TYPE (lhs);
    6132       173600 :   tree sarg0 = gimple_assign_rhs1 (stmt);
    6133       173600 :   tree sarg1 = gimple_assign_rhs2 (stmt);
    6134              : 
    6135       173600 :   if (TREE_CODE (stype) != INTEGER_TYPE
    6136       166342 :       || TREE_CODE (sarg1) != INTEGER_CST
    6137       149457 :       || TREE_CODE (sarg0) != SSA_NAME
    6138       149456 :       || !tree_fits_uhwi_p (sarg1)
    6139       323056 :       || !has_single_use (sarg0))
    6140              :     return false;
    6141              : 
    6142        48396 :   gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (sarg0));
    6143        45092 :   if (!def)
    6144              :     return false;
    6145              : 
    6146        45092 :   enum tree_code mcode = gimple_assign_rhs_code (def);
    6147        45092 :   if (mcode == NOP_EXPR)
    6148              :     {
    6149        11009 :       tree tmp = gimple_assign_rhs1 (def);
    6150        11009 :       if (TREE_CODE (tmp) != SSA_NAME || !has_single_use (tmp))
    6151              :         return false;
    6152         3742 :       def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (tmp));
    6153         3449 :       if (!def)
    6154              :         return false;
    6155         3449 :       mcode = gimple_assign_rhs_code (def);
    6156              :     }
    6157              : 
    6158        37532 :   if (mcode != WIDEN_MULT_EXPR
    6159        37532 :       || gimple_bb (def) != gimple_bb (stmt))
    6160              :     return false;
    6161         2581 :   tree mtype = TREE_TYPE (gimple_assign_lhs (def));
    6162         2581 :   if (TREE_CODE (mtype) != INTEGER_TYPE
    6163         2581 :       || TYPE_PRECISION (mtype) != TYPE_PRECISION (stype))
    6164              :     return false;
    6165              : 
    6166         2581 :   tree mop1 = gimple_assign_rhs1 (def);
    6167         2581 :   tree mop2 = gimple_assign_rhs2 (def);
    6168         2581 :   tree optype = TREE_TYPE (mop1);
    6169         2581 :   bool unsignedp = TYPE_UNSIGNED (optype);
    6170         2581 :   unsigned int prec = TYPE_PRECISION (optype);
    6171              : 
    6172         2581 :   if (unsignedp != TYPE_UNSIGNED (mtype)
    6173         2581 :       || TYPE_PRECISION (mtype) != 2 * prec)
    6174              :     return false;
    6175              : 
    6176         2581 :   unsigned HOST_WIDE_INT bits = tree_to_uhwi (sarg1);
    6177         2581 :   if (bits < prec || bits >= 2 * prec)
    6178              :     return false;
    6179              : 
    6180              :   /* For the time being, require operands to have the same sign.  */
    6181         2580 :   if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2)))
    6182              :     return false;
    6183              : 
    6184         2580 :   machine_mode mode = TYPE_MODE (optype);
    6185         2580 :   optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
    6186         2580 :   if (optab_handler (tab, mode) == CODE_FOR_nothing)
    6187              :     return false;
    6188              : 
    6189         2580 :   location_t loc = gimple_location (stmt);
    6190         2580 :   tree highpart1 = build_and_insert_binop (gsi, loc, "highparttmp",
    6191              :                                            MULT_HIGHPART_EXPR, mop1, mop2);
    6192         2580 :   tree highpart2 = highpart1;
    6193         2580 :   tree ntype = optype;
    6194              : 
    6195         2580 :   if (TYPE_UNSIGNED (stype) != TYPE_UNSIGNED (optype))
    6196              :     {
    6197           16 :       ntype = TYPE_UNSIGNED (stype) ? unsigned_type_for (optype)
    6198            7 :                                     : signed_type_for (optype);
    6199           16 :       highpart2 = build_and_insert_cast (gsi, loc, ntype, highpart1);
    6200              :     }
    6201         2580 :   if (bits > prec)
    6202           29 :     highpart2 = build_and_insert_binop (gsi, loc, "highparttmp",
    6203              :                                         RSHIFT_EXPR, highpart2,
    6204           29 :                                         build_int_cst (ntype, bits - prec));
    6205              : 
    6206         2580 :   gassign *new_stmt = gimple_build_assign (lhs, NOP_EXPR, highpart2);
    6207         2580 :   gsi_replace (gsi, new_stmt, true);
    6208              : 
    6209         2580 :   widen_mul_stats.highpart_mults_inserted++;
    6210         2580 :   return true;
    6211              : }
    6212              : 
    6213              : /* If target has spaceship<MODE>3 expander, pattern recognize
    6214              :    <bb 2> [local count: 1073741824]:
    6215              :    if (a_2(D) == b_3(D))
    6216              :      goto <bb 6>; [34.00%]
    6217              :    else
    6218              :      goto <bb 3>; [66.00%]
    6219              : 
    6220              :    <bb 3> [local count: 708669601]:
    6221              :    if (a_2(D) < b_3(D))
    6222              :      goto <bb 6>; [1.04%]
    6223              :    else
    6224              :      goto <bb 4>; [98.96%]
    6225              : 
    6226              :    <bb 4> [local count: 701299439]:
    6227              :    if (a_2(D) > b_3(D))
    6228              :      goto <bb 5>; [48.89%]
    6229              :    else
    6230              :      goto <bb 6>; [51.11%]
    6231              : 
    6232              :    <bb 5> [local count: 342865295]:
    6233              : 
    6234              :    <bb 6> [local count: 1073741824]:
    6235              :    and turn it into:
    6236              :    <bb 2> [local count: 1073741824]:
    6237              :    _1 = .SPACESHIP (a_2(D), b_3(D), 0);
    6238              :    if (_1 == 0)
    6239              :      goto <bb 6>; [34.00%]
    6240              :    else
    6241              :      goto <bb 3>; [66.00%]
    6242              : 
    6243              :    <bb 3> [local count: 708669601]:
    6244              :    if (_1 == -1)
    6245              :      goto <bb 6>; [1.04%]
    6246              :    else
    6247              :      goto <bb 4>; [98.96%]
    6248              : 
    6249              :    <bb 4> [local count: 701299439]:
    6250              :    if (_1 == 1)
    6251              :      goto <bb 5>; [48.89%]
    6252              :    else
    6253              :      goto <bb 6>; [51.11%]
    6254              : 
    6255              :    <bb 5> [local count: 342865295]:
    6256              : 
    6257              :    <bb 6> [local count: 1073741824]:
    6258              :    so that the backend can emit optimal comparison and
    6259              :    conditional jump sequence.  If the
    6260              :    <bb 6> [local count: 1073741824]:
    6261              :    above has a single PHI like:
    6262              :    # _27 = PHI<0(2), -1(3), -128(4), 1(5)>
    6263              :    then replace it with effectively
    6264              :    _1 = .SPACESHIP (a_2(D), b_3(D), -128);
    6265              :    _27 = _1;  */
    6266              : 
    6267              : static void
    6268      4219657 : optimize_spaceship (gcond *stmt)
    6269              : {
    6270      4219657 :   enum tree_code code = gimple_cond_code (stmt);
    6271      4219657 :   if (code != EQ_EXPR && code != NE_EXPR)
    6272      4219533 :     return;
    6273      3425386 :   tree arg1 = gimple_cond_lhs (stmt);
    6274      3425386 :   tree arg2 = gimple_cond_rhs (stmt);
    6275      3425386 :   if ((!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1))
    6276      3314269 :        && !INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
    6277      2650379 :       || optab_handler (spaceship_optab,
    6278      2650379 :                         TYPE_MODE (TREE_TYPE (arg1))) == CODE_FOR_nothing
    6279      6035294 :       || operand_equal_p (arg1, arg2, 0))
    6280              :     return;
    6281              : 
    6282      2608685 :   basic_block bb0 = gimple_bb (stmt), bb1, bb2 = NULL;
    6283      2608685 :   edge em1 = NULL, e1 = NULL, e2 = NULL;
    6284      2608685 :   bb1 = EDGE_SUCC (bb0, 1)->dest;
    6285      2608685 :   if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
    6286      1578482 :     bb1 = EDGE_SUCC (bb0, 0)->dest;
    6287              : 
    6288      9395156 :   gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
    6289      1138870 :   if (g == NULL
    6290      4826492 :       || !single_pred_p (bb1)
    6291       724255 :       || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6292       606959 :           ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
    6293       489663 :           : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
    6294          948 :              || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
    6295       619320 :       || !cond_only_block_p (bb1))
    6296              :     return;
    6297              : 
    6298        11626 :   enum tree_code ccode = (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6299        11626 :                           ? LT_EXPR : GT_EXPR);
    6300        11626 :   switch (gimple_cond_code (g))
    6301              :     {
    6302              :     case LT_EXPR:
    6303              :     case LE_EXPR:
    6304              :       break;
    6305        10165 :     case GT_EXPR:
    6306        10165 :     case GE_EXPR:
    6307        10165 :       ccode = ccode == LT_EXPR ? GT_EXPR : LT_EXPR;
    6308              :       break;
    6309              :     default:
    6310              :       return;
    6311              :     }
    6312              : 
    6313        34806 :   for (int i = 0; i < 2; ++i)
    6314              :     {
    6315              :       /* With NaNs, </<=/>/>= are false, so we need to look for the
    6316              :          third comparison on the false edge from whatever non-equality
    6317              :          comparison the second comparison is.  */
    6318        23246 :       if (HONOR_NANS (TREE_TYPE (arg1))
    6319        23246 :           && (EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0)
    6320          131 :         continue;
    6321              : 
    6322        23115 :       bb2 = EDGE_SUCC (bb1, i)->dest;
    6323        68947 :       g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
    6324        15597 :       if (g == NULL
    6325        15597 :           || !single_pred_p (bb2)
    6326        19266 :           || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
    6327        11521 :               ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
    6328         3776 :               : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
    6329           19 :                  || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
    6330           66 :           || !cond_only_block_p (bb2)
    6331        11587 :           || EDGE_SUCC (bb2, 0)->dest == EDGE_SUCC (bb2, 1)->dest)
    6332        23049 :         continue;
    6333              : 
    6334           66 :       enum tree_code ccode2
    6335           66 :         = (operand_equal_p (gimple_cond_lhs (g), arg1, 0) ? LT_EXPR : GT_EXPR);
    6336           66 :       switch (gimple_cond_code (g))
    6337              :         {
    6338              :         case LT_EXPR:
    6339              :         case LE_EXPR:
    6340              :           break;
    6341           41 :         case GT_EXPR:
    6342           41 :         case GE_EXPR:
    6343           41 :           ccode2 = ccode2 == LT_EXPR ? GT_EXPR : LT_EXPR;
    6344              :           break;
    6345            0 :         default:
    6346            0 :           continue;
    6347              :         }
    6348           66 :       if (HONOR_NANS (TREE_TYPE (arg1)) && ccode == ccode2)
    6349            0 :         continue;
    6350              : 
    6351          132 :       if ((ccode == LT_EXPR)
    6352           66 :           ^ ((EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0))
    6353              :         {
    6354           41 :           em1 = EDGE_SUCC (bb1, 1 - i);
    6355           41 :           e1 = EDGE_SUCC (bb2, 0);
    6356           41 :           e2 = EDGE_SUCC (bb2, 1);
    6357           41 :           if ((ccode2 == LT_EXPR) ^ ((e1->flags & EDGE_TRUE_VALUE) == 0))
    6358            0 :             std::swap (e1, e2);
    6359              :         }
    6360              :       else
    6361              :         {
    6362           25 :           e1 = EDGE_SUCC (bb1, 1 - i);
    6363           25 :           em1 = EDGE_SUCC (bb2, 0);
    6364           25 :           e2 = EDGE_SUCC (bb2, 1);
    6365           25 :           if ((ccode2 != LT_EXPR) ^ ((em1->flags & EDGE_TRUE_VALUE) == 0))
    6366              :             std::swap (em1, e2);
    6367              :         }
    6368              :       break;
    6369              :     }
    6370              : 
    6371        11601 :   if (em1 == NULL)
    6372              :     {
    6373        23120 :       if ((ccode == LT_EXPR)
    6374        11560 :           ^ ((EDGE_SUCC (bb1, 0)->flags & EDGE_TRUE_VALUE) != 0))
    6375              :         {
    6376         4656 :           em1 = EDGE_SUCC (bb1, 1);
    6377         4656 :           e1 = EDGE_SUCC (bb1, 0);
    6378         4656 :           e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
    6379              :         }
    6380              :       else
    6381              :         {
    6382         6904 :           em1 = EDGE_SUCC (bb1, 0);
    6383         6904 :           e1 = EDGE_SUCC (bb1, 1);
    6384         6904 :           e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
    6385              :         }
    6386              :     }
    6387              : 
    6388              :   /* Check if there is a single bb into which all failed conditions
    6389              :      jump to (perhaps through an empty block) and if it results in
    6390              :      a single integral PHI which just sets it to -1, 0, 1, X
    6391              :      (or -1, 0, 1 when NaNs can't happen).  In that case use 1 rather
    6392              :      than 0 as last .SPACESHIP argument to tell backends it might
    6393              :      consider different code generation and just cast the result
    6394              :      of .SPACESHIP to the PHI result.  X above is some value
    6395              :      other than -1, 0, 1, for libstdc++ -128, for libc++ -127.  */
    6396        11626 :   tree arg3 = integer_zero_node;
    6397        11626 :   edge e = EDGE_SUCC (bb0, 0);
    6398        11626 :   if (e->dest == bb1)
    6399         8924 :     e = EDGE_SUCC (bb0, 1);
    6400        11626 :   basic_block bbp = e->dest;
    6401        11626 :   gphi *phi = NULL;
    6402        11626 :   for (gphi_iterator psi = gsi_start_phis (bbp);
    6403        13767 :        !gsi_end_p (psi); gsi_next (&psi))
    6404              :     {
    6405         3682 :       gphi *gp = psi.phi ();
    6406         3682 :       tree res = gimple_phi_result (gp);
    6407              : 
    6408         3682 :       if (phi != NULL
    6409         3345 :           || virtual_operand_p (res)
    6410         2429 :           || !INTEGRAL_TYPE_P (TREE_TYPE (res))
    6411         5956 :           || TYPE_PRECISION (TREE_TYPE (res)) < 2)
    6412              :         {
    6413              :           phi = NULL;
    6414              :           break;
    6415              :         }
    6416         2141 :       phi = gp;
    6417              :     }
    6418        11626 :   if (phi
    6419         1804 :       && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
    6420        12202 :       && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
    6421              :     {
    6422          122 :       HOST_WIDE_INT argval
    6423          122 :         = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? -128 : -1;
    6424          708 :       for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
    6425              :         {
    6426          255 :           edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
    6427          255 :           if (e3->dest != bbp)
    6428              :             {
    6429          117 :               if (!empty_block_p (e3->dest)
    6430          108 :                   || !single_succ_p (e3->dest)
    6431          225 :                   || single_succ (e3->dest) != bbp)
    6432              :                 {
    6433              :                   phi = NULL;
    6434              :                   break;
    6435              :                 }
    6436              :               e3 = single_succ_edge (e3->dest);
    6437              :             }
    6438          246 :           tree a = gimple_phi_arg_def_from_edge (phi, e3);
    6439          246 :           if (TREE_CODE (a) != INTEGER_CST
    6440          246 :               || (i == 0 && !integer_onep (a))
    6441          482 :               || (i == 1 && !integer_all_onesp (a)))
    6442              :             {
    6443              :               phi = NULL;
    6444              :               break;
    6445              :             }
    6446          236 :           if (i == 2)
    6447              :             {
    6448           30 :               tree minv = TYPE_MIN_VALUE (signed_char_type_node);
    6449           30 :               tree maxv = TYPE_MAX_VALUE (signed_char_type_node);
    6450           30 :               widest_int w = widest_int::from (wi::to_wide (a), SIGNED);
    6451           41 :               if ((w >= -1 && w <= 1)
    6452           26 :                   || w < wi::to_widest (minv)
    6453           60 :                   || w > wi::to_widest (maxv))
    6454              :                 {
    6455            4 :                   phi = NULL;
    6456            4 :                   break;
    6457              :                 }
    6458           26 :               argval = w.to_shwi ();
    6459           26 :             }
    6460              :         }
    6461          122 :       if (phi)
    6462           99 :         arg3 = build_int_cst (integer_type_node,
    6463          119 :                               TYPE_UNSIGNED (TREE_TYPE (arg1)) ? 1 : argval);
    6464              :     }
    6465              : 
    6466              :   /* For integral <=> comparisons only use .SPACESHIP if it is turned
    6467              :      into an integer (-1, 0, 1).  */
    6468        11626 :   if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) && arg3 == integer_zero_node)
    6469              :     return;
    6470              : 
    6471          223 :   gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 3, arg1, arg2, arg3);
    6472          223 :   tree lhs = make_ssa_name (integer_type_node);
    6473          223 :   gimple_call_set_lhs (gc, lhs);
    6474          223 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    6475          223 :   gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
    6476              : 
    6477          347 :   wide_int wmin = wi::minus_one (TYPE_PRECISION (integer_type_node));
    6478          347 :   wide_int wmax = wi::one (TYPE_PRECISION (integer_type_node));
    6479          223 :   if (HONOR_NANS (TREE_TYPE (arg1)))
    6480              :     {
    6481          131 :       if (arg3 == integer_zero_node)
    6482          105 :         wmin = wi::shwi (-128, TYPE_PRECISION (integer_type_node));
    6483           26 :       else if (tree_int_cst_sgn (arg3) < 0)
    6484           19 :         wmin = wi::to_wide (arg3);
    6485              :       else
    6486            7 :         wmax = wi::to_wide (arg3);
    6487              :     }
    6488          347 :   int_range<1> vr (TREE_TYPE (lhs), wmin, wmax);
    6489          223 :   set_range_info (lhs, vr);
    6490              : 
    6491          223 :   if (arg3 != integer_zero_node)
    6492              :     {
    6493           99 :       tree type = TREE_TYPE (gimple_phi_result (phi));
    6494           99 :       if (!useless_type_conversion_p (type, integer_type_node))
    6495              :         {
    6496           63 :           tree tem = make_ssa_name (type);
    6497           63 :           gimple *gcv = gimple_build_assign (tem, NOP_EXPR, lhs);
    6498           63 :           gsi_insert_before (&gsi, gcv, GSI_SAME_STMT);
    6499           63 :           lhs = tem;
    6500              :         }
    6501           99 :       SET_PHI_ARG_DEF_ON_EDGE (phi, e, lhs);
    6502           99 :       gimple_cond_set_lhs (stmt, boolean_false_node);
    6503           99 :       gimple_cond_set_rhs (stmt, boolean_false_node);
    6504          185 :       gimple_cond_set_code (stmt, (e->flags & EDGE_TRUE_VALUE)
    6505              :                                   ? EQ_EXPR : NE_EXPR);
    6506           99 :       update_stmt (stmt);
    6507           99 :       return;
    6508              :     }
    6509              : 
    6510          124 :   gimple_cond_set_lhs (stmt, lhs);
    6511          124 :   gimple_cond_set_rhs (stmt, integer_zero_node);
    6512          124 :   update_stmt (stmt);
    6513              : 
    6514          248 :   gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
    6515          124 :   gimple_cond_set_lhs (cond, lhs);
    6516          124 :   if (em1->src == bb1 && e2 != em1)
    6517              :     {
    6518           68 :       gimple_cond_set_rhs (cond, integer_minus_one_node);
    6519           74 :       gimple_cond_set_code (cond, (em1->flags & EDGE_TRUE_VALUE)
    6520              :                                   ? EQ_EXPR : NE_EXPR);
    6521              :     }
    6522              :   else
    6523              :     {
    6524           56 :       gcc_assert (e1->src == bb1 && e2 != e1);
    6525           56 :       gimple_cond_set_rhs (cond, integer_one_node);
    6526           56 :       gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
    6527              :                                   ? EQ_EXPR : NE_EXPR);
    6528              :     }
    6529          124 :   update_stmt (cond);
    6530              : 
    6531          124 :   if (e2 != e1 && e2 != em1)
    6532              :     {
    6533           80 :       cond = as_a <gcond *> (*gsi_last_bb (bb2));
    6534           40 :       gimple_cond_set_lhs (cond, lhs);
    6535           40 :       if (em1->src == bb2)
    6536           25 :         gimple_cond_set_rhs (cond, integer_minus_one_node);
    6537              :       else
    6538              :         {
    6539           15 :           gcc_assert (e1->src == bb2);
    6540           15 :           gimple_cond_set_rhs (cond, integer_one_node);
    6541              :         }
    6542           40 :       gimple_cond_set_code (cond,
    6543           40 :                             (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
    6544           40 :       update_stmt (cond);
    6545              :     }
    6546              : }
    6547              : 
    6548              : 
    6549              : /* Long-multiply inverse-lowering helper.
    6550              : 
    6551              :    The forwprop long-multiply recognizer canonicalizes a hand-written
    6552              :    longhand high-part multiply into a cast+mult+shift+cast chain
    6553              :    `(N) ((2N) a * (2N) b) >> N'.  When the target lacks an expansion
    6554              :    path for the wide form, `lower_long_mul_high_chain' resynthesizes
    6555              :    the longhand at narrow precision via `build_long_mul_partials'.  */
    6556              : 
    6557              : /* Test whether the target supports an (HALF)-by-(HALF)->NARROW unsigned
    6558              :    widening multiply.  Returns true on success, with the half-width
    6559              :    scalar int mode placed in *HALF_MODE.  */
    6560              : 
    6561              : static bool
    6562         2231 : can_widen_to_narrow_p (scalar_int_mode narrow_mode, unsigned int half_width,
    6563              :                        scalar_int_mode *half_mode)
    6564              : {
    6565         2231 :   if (!int_mode_for_size (half_width, 0).exists (half_mode))
    6566            0 :     return false;
    6567         2231 :   return convert_optab_handler (umul_widen_optab, narrow_mode, *half_mode)
    6568         2231 :          != CODE_FOR_nothing;
    6569              : }
    6570              : 
    6571              : /* Append to *SEQ the operand split and partial products for an unsigned
    6572              :    long multiply of OP1 by OP2 at the precision of TREE_TYPE (OP1).
    6573              :    HALF_TYPE is the (N/2)-bit unsigned type; HALF_AMT is the integer-typed
    6574              :    shift constant equal to N/2.
    6575              : 
    6576              :    Outputs the four partial products via *LOLO, *HILO, *LOHI, *HIHI.
    6577              : 
    6578              :    USE_WIDEN selects the partial-product form:
    6579              :      true  - cast halves to HALF_TYPE and use WIDEN_MULT_EXPR (needs
    6580              :              an (N/2)-by-(N/2)->N widening multiply optab).
    6581              :      false - mask/shift halves within the N-bit accumulator and use
    6582              :              plain MULT_EXPR; the halves fit in N/2 bits so the N-bit
    6583              :              low product is exact.  */
    6584              : 
    6585              : static void
    6586         2231 : build_long_mul_partials (gimple_seq *seq, location_t loc, tree op1, tree op2,
    6587              :                          tree half_type, tree half_amt,
    6588              :                          tree *lolo, tree *hilo, tree *lohi, tree *hihi,
    6589              :                          bool use_widen)
    6590              : {
    6591         2231 :   tree acc_type = TREE_TYPE (op1);
    6592         2231 :   tree op1_hi = gimple_build (seq, loc, RSHIFT_EXPR, acc_type, op1, half_amt);
    6593         2231 :   tree op2_hi = gimple_build (seq, loc, RSHIFT_EXPR, acc_type, op2, half_amt);
    6594         2231 :   tree op1_lo, op2_lo;
    6595         2231 :   tree_code mul_code;
    6596              : 
    6597         2231 :   if (use_widen)
    6598              :     {
    6599         2231 :       op1_lo = gimple_build (seq, loc, NOP_EXPR, half_type, op1);
    6600         2231 :       op2_lo = gimple_build (seq, loc, NOP_EXPR, half_type, op2);
    6601         2231 :       op1_hi = gimple_build (seq, loc, NOP_EXPR, half_type, op1_hi);
    6602         2231 :       op2_hi = gimple_build (seq, loc, NOP_EXPR, half_type, op2_hi);
    6603         2231 :       mul_code = WIDEN_MULT_EXPR;
    6604              :     }
    6605              :   else
    6606              :     {
    6607            0 :       tree mask = wide_int_to_tree (acc_type,
    6608            0 :                                     wi::mask (TYPE_PRECISION (half_type), false,
    6609            0 :                                               TYPE_PRECISION (acc_type)));
    6610            0 :       op1_lo = gimple_build (seq, loc, BIT_AND_EXPR, acc_type, op1, mask);
    6611            0 :       op2_lo = gimple_build (seq, loc, BIT_AND_EXPR, acc_type, op2, mask);
    6612            0 :       mul_code = MULT_EXPR;
    6613              :     }
    6614              : 
    6615         2231 :   *lolo = gimple_build (seq, loc, mul_code, acc_type, op1_lo, op2_lo);
    6616         2231 :   *hilo = gimple_build (seq, loc, mul_code, acc_type, op1_hi, op2_lo);
    6617         2231 :   *lohi = gimple_build (seq, loc, mul_code, acc_type, op1_lo, op2_hi);
    6618         2231 :   *hihi = gimple_build (seq, loc, mul_code, acc_type, op1_hi, op2_hi);
    6619         2231 : }
    6620              : 
    6621              : /* Emit into *SEQ the high N bits of the unsigned product A * B, where A and B
    6622              :    are NARROW_TYPE (N-bit) values, as a longhand over (N/2)-bit partials.
    6623              :    Returns the high-part SSA.  */
    6624              : 
    6625              : static tree
    6626         2231 : emit_long_mul_highpart (gimple_seq *seq, location_t loc, tree a, tree b,
    6627              :                         tree narrow_type)
    6628              : {
    6629         2231 :   scalar_int_mode narrow_mode
    6630         2231 :     = as_a <scalar_int_mode> (TYPE_MODE (narrow_type));
    6631         2231 :   unsigned int half_width = GET_MODE_PRECISION (narrow_mode) / 2;
    6632              :   /* Prefer (N/2)-by-(N/2)->N widening partials; fall back to plain MULT_EXPR
    6633              :      when the target lacks the widen optab.  See build_long_mul_partials.  */
    6634         2231 :   scalar_int_mode half_mode;
    6635         2231 :   bool use_widen = can_widen_to_narrow_p (narrow_mode, half_width, &half_mode);
    6636         2231 :   tree half_type = build_nonstandard_integer_type (half_width, 1);
    6637         2231 :   tree half_amt = build_int_cst (integer_type_node, half_width);
    6638         2231 :   tree half_mask = wide_int_to_tree (narrow_type,
    6639         2231 :                                      wi::mask (half_width, false,
    6640         2231 :                                                TYPE_PRECISION (narrow_type)));
    6641              : 
    6642         2231 :   tree lolo, hilo, lohi, hihi;
    6643         2231 :   build_long_mul_partials (seq, loc, a, b, half_type, half_amt,
    6644              :                            &lolo, &hilo, &lohi, &hihi, use_widen);
    6645         2231 :   tree cross_sum = gimple_build (seq, loc, PLUS_EXPR, narrow_type, hilo, lohi);
    6646         2231 :   tree cross_lt = gimple_build (seq, loc, LT_EXPR, boolean_type_node,
    6647              :                                 cross_sum, hilo);
    6648         2231 :   tree cross_lt_n = gimple_build (seq, loc, NOP_EXPR, narrow_type, cross_lt);
    6649         2231 :   tree cross_carry = gimple_build (seq, loc, LSHIFT_EXPR, narrow_type,
    6650              :                                    cross_lt_n, half_amt);
    6651         2231 :   tree lolo_hi = gimple_build (seq, loc, RSHIFT_EXPR, narrow_type,
    6652              :                                lolo, half_amt);
    6653         2231 :   tree cross_lo = gimple_build (seq, loc, BIT_AND_EXPR, narrow_type,
    6654              :                                 cross_sum, half_mask);
    6655         2231 :   tree low_accum = gimple_build (seq, loc, PLUS_EXPR, narrow_type,
    6656              :                                  lolo_hi, cross_lo);
    6657         2231 :   tree low_accum_hi = gimple_build (seq, loc, RSHIFT_EXPR, narrow_type,
    6658              :                                     low_accum, half_amt);
    6659         2231 :   tree cross_hi = gimple_build (seq, loc, RSHIFT_EXPR, narrow_type,
    6660              :                                 cross_sum, half_amt);
    6661         2231 :   tree t1 = gimple_build (seq, loc, PLUS_EXPR, narrow_type, hihi, cross_hi);
    6662         2231 :   tree t2 = gimple_build (seq, loc, PLUS_EXPR, narrow_type, t1, low_accum_hi);
    6663         2231 :   return gimple_build (seq, loc, PLUS_EXPR, narrow_type, t2, cross_carry);
    6664              : }
    6665              : 
    6666              : /* Emit into *SEQ the high N bits (NARROW_TYPE) of the unsigned product of two
    6667              :    2N-bit values given as N-bit halves, x = L1 + H1*2^N and y = L2 + H2*2^N:
    6668              :    the high half of x*y is the high N bits of L1*L2, plus H1*L2 and L1*H2, all
    6669              :    mod 2^N.  */
    6670              : 
    6671              : static tree
    6672         2231 : combine_long_mul_halves (gimple_seq *seq, location_t loc, tree l1, tree h1,
    6673              :                          tree l2, tree h2, tree narrow_type)
    6674              : {
    6675         2231 :   tree hh = emit_long_mul_highpart (seq, loc, l1, l2, narrow_type);
    6676         2231 :   tree c1 = gimple_build (seq, loc, MULT_EXPR, narrow_type, h1, l2);
    6677         2231 :   tree c2 = gimple_build (seq, loc, MULT_EXPR, narrow_type, l1, h2);
    6678         2231 :   tree s = gimple_build (seq, loc, PLUS_EXPR, narrow_type, hh, c1);
    6679         2231 :   return gimple_build (seq, loc, PLUS_EXPR, narrow_type, s, c2);
    6680              : }
    6681              : 
    6682              : /* True when OP fits NARROW_PREC bits as an unsigned value.  Looks
    6683              :    through widening casts and PHIs, falling back to `tree_nonzero_bits'
    6684              :    otherwise.  PHI_SEEN guards against cycles.  */
    6685              : 
    6686              : static bool
    6687          929 : long_mul_op_fits_p (tree op, unsigned narrow_prec, bitmap phi_seen)
    6688              : {
    6689         1199 :   if (!TYPE_UNSIGNED (TREE_TYPE (op)))
    6690              :     return false;
    6691         1199 :   if (TYPE_PRECISION (TREE_TYPE (op)) <= narrow_prec)
    6692              :     return true;
    6693          929 :   if (TREE_CODE (op) == SSA_NAME)
    6694              :     {
    6695          357 :       gimple *def = SSA_NAME_DEF_STMT (op);
    6696          357 :       if (is_gimple_assign (def)
    6697          357 :           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
    6698          270 :         return long_mul_op_fits_p (gimple_assign_rhs1 (def), narrow_prec,
    6699          270 :                                    phi_seen);
    6700           87 :       if (gphi *phi = dyn_cast <gphi *> (def))
    6701           69 :         if (bitmap_set_bit (phi_seen, SSA_NAME_VERSION (op)))
    6702              :           {
    6703          404 :             for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
    6704          335 :               if (!long_mul_op_fits_p (gimple_phi_arg_def (phi, i),
    6705              :                                        narrow_prec, phi_seen))
    6706              :                 return false;
    6707              :             return true;
    6708              :           }
    6709              :     }
    6710          590 :   return wi::min_precision (tree_nonzero_bits (op), UNSIGNED) <= narrow_prec;
    6711              : }
    6712              : 
    6713              : static bool long_mul_split_operand (gimple_seq *, location_t, tree, tree,
    6714              :                                     tree *, tree *);
    6715              : 
    6716              : struct long_mul_halves
    6717              : {
    6718              :   tree lo;
    6719              :   tree hi;
    6720              : };
    6721              : 
    6722              : /* Halves recorded for one run of the pass, keyed on the PHI they came from.
    6723              :    Several chains can reach one operand PHI, and each that splits it again
    6724              :    leaves another redundant pair of half PHIs behind.  */
    6725              : 
    6726              : static hash_map<tree, long_mul_halves> *long_mul_phi_halves;
    6727              : 
    6728              : struct long_mul_arg_split
    6729              : {
    6730              :   gimple_seq seq;
    6731              :   tree lo;
    6732              :   tree hi;
    6733              : };
    6734              : 
    6735              : /* Split the 2N-bit result of PHI into N-bit halves *LO and *HI, by splitting
    6736              :    each argument and merging the halves with two new PHIs.  A split goes at
    6737              :    the end of its argument's incoming block, where the argument is available,
    6738              :    rather than on the edge, which could split a critical edge while the
    6739              :    dominator walk is still running.  Returns false, having changed nothing,
    6740              :    when an argument cannot be split.  A split that succeeds stands even if
    6741              :    the caller then gives up.  */
    6742              : 
    6743              : static bool
    6744            0 : long_mul_split_phi (gphi *phi, tree narrow_type, tree *lo, tree *hi)
    6745              : {
    6746            0 :   tree res = gimple_phi_result (phi);
    6747            0 :   if (long_mul_halves *prev = long_mul_phi_halves->get (res))
    6748              :     {
    6749              :       /* Every operand reaching a split has the 2N type, so the width is
    6750              :          fixed by the PHI's own type.  */
    6751            0 :       gcc_checking_assert (types_compatible_p (TREE_TYPE (prev->lo),
    6752              :                                                narrow_type));
    6753            0 :       *lo = prev->lo;
    6754            0 :       *hi = prev->hi;
    6755            0 :       return true;
    6756              :     }
    6757              : 
    6758            0 :   unsigned int n = gimple_phi_num_args (phi);
    6759            0 :   location_t loc = gimple_location (phi);
    6760            0 :   basic_block bb = gimple_bb (phi);
    6761            0 :   auto_vec<long_mul_arg_split, 4> args;
    6762              : 
    6763            0 :   for (unsigned int i = 0; i < n; i++)
    6764              :     {
    6765            0 :       edge e = gimple_phi_arg_edge (phi, i);
    6766              :       /* A back edge could lead back to PHI and recurse forever.  The entry
    6767              :          block cannot hold a split.  */
    6768            0 :       if (dominated_by_p (CDI_DOMINATORS, e->src, bb)
    6769            0 :           || e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    6770            0 :         return false;
    6771              : 
    6772            0 :       long_mul_arg_split arg = {};
    6773            0 :       if (!long_mul_split_operand (&arg.seq, loc, gimple_phi_arg_def (phi, i),
    6774              :                                    narrow_type, &arg.lo, &arg.hi))
    6775              :         return false;
    6776              : 
    6777            0 :       args.safe_push (arg);
    6778              :     }
    6779              : 
    6780              :   /* Every argument split, so the rewrite can be committed.  */
    6781            0 :   gphi *lo_phi = create_phi_node (make_ssa_name (narrow_type), bb);
    6782            0 :   gphi *hi_phi = create_phi_node (make_ssa_name (narrow_type), bb);
    6783            0 :   for (unsigned int i = 0; i < n; i++)
    6784              :     {
    6785            0 :       edge e = gimple_phi_arg_edge (phi, i);
    6786            0 :       if (args[i].seq)
    6787              :         {
    6788            0 :           gimple_stmt_iterator gsi = gsi_last_bb (e->src);
    6789            0 :           if (!gsi_end_p (gsi) && stmt_ends_bb_p (gsi_stmt (gsi)))
    6790            0 :             gsi_insert_seq_before (&gsi, args[i].seq, GSI_SAME_STMT);
    6791              :           else
    6792            0 :             gsi_insert_seq_after (&gsi, args[i].seq, GSI_CONTINUE_LINKING);
    6793              :         }
    6794            0 :       add_phi_arg (lo_phi, args[i].lo, e, UNKNOWN_LOCATION);
    6795            0 :       add_phi_arg (hi_phi, args[i].hi, e, UNKNOWN_LOCATION);
    6796              :     }
    6797            0 :   *lo = gimple_phi_result (lo_phi);
    6798            0 :   *hi = gimple_phi_result (hi_phi);
    6799            0 :   long_mul_phi_halves->put (res, { *lo, *hi });
    6800              : 
    6801            0 :   if (dump_file && (dump_flags & TDF_DETAILS))
    6802            0 :     fprintf (dump_file, "Split long-multiply operand PHI.\n");
    6803              :   return true;
    6804            0 : }
    6805              : 
    6806              : /* Split the 2N-bit unsigned value OP into its low and high N bits (*LO and
    6807              :    *HI, both NARROW_TYPE) using only N-bit operations, as the target has no 2N
    6808              :    multiply or shift.  A 2N product recurses on its operands, its high half
    6809              :    coming from combine_long_mul_halves.  A value shifted down by N recurses on
    6810              :    the shifted value and takes its high half, rather than reading the 2N shift.
    6811              :    A widening cast's low half is the truncated source and its high half is what
    6812              :    the cast extended with, zero or the source's replicated sign bit.  A value
    6813              :    that provably fits N bits has a zero high half.  A PHI is split through its
    6814              :    arguments as a last resort.  Returns false otherwise.  */
    6815              : 
    6816              : static bool
    6817         4470 : long_mul_split_operand (gimple_seq *seq, location_t loc, tree op,
    6818              :                         tree narrow_type, tree *lo, tree *hi)
    6819              : {
    6820         4470 :   unsigned int narrow_prec = TYPE_PRECISION (narrow_type);
    6821         4470 :   if (TREE_CODE (op) == SSA_NAME)
    6822              :     {
    6823         3943 :       gimple *def = SSA_NAME_DEF_STMT (op);
    6824         3943 :       if (is_gimple_assign (def) && gimple_assign_rhs_code (def) == MULT_EXPR)
    6825              :         {
    6826           13 :           tree a_lo, a_hi, b_lo, b_hi;
    6827           13 :           if (!long_mul_split_operand (seq, loc, gimple_assign_rhs1 (def),
    6828              :                                        narrow_type, &a_lo, &a_hi)
    6829           13 :               || !long_mul_split_operand (seq, loc, gimple_assign_rhs2 (def),
    6830              :                                           narrow_type, &b_lo, &b_hi))
    6831              :             return false;
    6832           13 :           *lo = gimple_build (seq, loc, MULT_EXPR, narrow_type, a_lo, b_lo);
    6833           13 :           *hi = combine_long_mul_halves (seq, loc, a_lo, a_hi, b_lo, b_hi,
    6834              :                                          narrow_type);
    6835           13 :           return true;
    6836              :         }
    6837              :       /* A 2N value shifted down by N is its own high half: split the source
    6838              :          and use that half.  Reading the shift instead leaves the 2N source
    6839              :          live, and the target cannot expand it.  This has to come before the
    6840              :          widening-cast case below, which would take such a value as it
    6841              :          stands.  */
    6842         3930 :       if (is_gimple_assign (def)
    6843         3881 :           && gimple_assign_rhs_code (def) == RSHIFT_EXPR
    6844            8 :           && tree_fits_uhwi_p (gimple_assign_rhs2 (def))
    6845         3938 :           && tree_to_uhwi (gimple_assign_rhs2 (def)) == narrow_prec)
    6846              :         {
    6847            8 :           tree src_lo, src_hi;
    6848            8 :           if (!long_mul_split_operand (seq, loc, gimple_assign_rhs1 (def),
    6849              :                                        narrow_type, &src_lo, &src_hi))
    6850              :             return false;
    6851            8 :           *lo = src_hi;
    6852            8 :           *hi = build_zero_cst (narrow_type);
    6853            8 :           return true;
    6854              :         }
    6855         3922 :       if (is_gimple_assign (def)
    6856         3922 :           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
    6857              :         {
    6858         3855 :           tree src = gimple_assign_rhs1 (def);
    6859         3855 :           tree src_type = TREE_TYPE (src);
    6860         3855 :           if (INTEGRAL_TYPE_P (src_type)
    6861         3855 :               && TYPE_PRECISION (src_type) <= narrow_prec)
    6862              :             {
    6863         3855 :               *lo = gimple_convert (seq, loc, narrow_type, src);
    6864         3855 :               if (TYPE_UNSIGNED (src_type))
    6865         3840 :                 *hi = build_zero_cst (narrow_type);
    6866              :               else
    6867              :                 {
    6868              :                   /* Sign extension: the high N bits replicate the sign bit.  */
    6869           15 :                   tree snarrow = signed_type_for (narrow_type);
    6870           15 :                   tree s = gimple_convert (seq, loc, snarrow, *lo);
    6871           15 :                   tree amt = build_int_cst (integer_type_node, narrow_prec - 1);
    6872           15 :                   tree sh = gimple_build (seq, loc, RSHIFT_EXPR, snarrow, s,
    6873              :                                           amt);
    6874           15 :                   *hi = gimple_convert (seq, loc, narrow_type, sh);
    6875              :                 }
    6876         3855 :               return true;
    6877              :             }
    6878              :         }
    6879              :     }
    6880              : 
    6881              :   /* A value provably within N bits: its low half is the truncation to N bits
    6882              :      (a subreg, not a 2N shift), its high half is zero.  */
    6883          594 :   auto_bitmap phi_seen;
    6884          594 :   if (long_mul_op_fits_p (op, narrow_prec, phi_seen))
    6885              :     {
    6886          594 :       *lo = gimple_convert (seq, loc, narrow_type, op);
    6887          594 :       *hi = build_zero_cst (narrow_type);
    6888          594 :       return true;
    6889              :     }
    6890              : 
    6891              :   /* A PHI that does not fit N bits can still be split through its arguments,
    6892              :      which is how a sign-extended value reaches the cast case above.  */
    6893            0 :   if (TREE_CODE (op) == SSA_NAME)
    6894          594 :     if (gphi *phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (op)))
    6895            0 :       return long_mul_split_phi (phi, narrow_type, lo, hi);
    6896              :   return false;
    6897          594 : }
    6898              : 
    6899              : /* Collect into HIGH_USES the uses of PROD forming its high half,
    6900              :    `PROD >> NARROW_PREC'.  A use reading only the low NARROW_PREC bits is
    6901              :    accepted but not collected.  Returns false on any other use.  */
    6902              : 
    6903              : static bool
    6904         2244 : long_mul_high_half_uses (tree prod, unsigned int narrow_prec,
    6905              :                          vec<gimple *> *high_uses)
    6906              : {
    6907         2244 :   imm_use_iterator iui;
    6908         2244 :   gimple *use_stmt;
    6909         4486 :   FOR_EACH_IMM_USE_STMT (use_stmt, iui, prod)
    6910              :     {
    6911         2247 :       if (is_gimple_debug (use_stmt))
    6912            0 :         continue;
    6913         2247 :       if (!is_gimple_assign (use_stmt))
    6914              :         return false;
    6915         2247 :       tree_code code = gimple_assign_rhs_code (use_stmt);
    6916         2247 :       if (code == RSHIFT_EXPR
    6917         2226 :           && gimple_assign_rhs1 (use_stmt) == prod
    6918         2226 :           && tree_fits_uhwi_p (gimple_assign_rhs2 (use_stmt))
    6919         4473 :           && tree_to_uhwi (gimple_assign_rhs2 (use_stmt)) == narrow_prec)
    6920         2226 :         high_uses->safe_push (use_stmt);
    6921           21 :       else if (CONVERT_EXPR_CODE_P (code))
    6922              :         {
    6923            0 :           tree t = TREE_TYPE (gimple_assign_lhs (use_stmt));
    6924            0 :           if (!INTEGRAL_TYPE_P (t) || TYPE_PRECISION (t) > narrow_prec)
    6925              :             return false;
    6926              :         }
    6927           21 :       else if (code == BIT_AND_EXPR
    6928           21 :                && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
    6929              :         {
    6930           16 :           if (wi::min_precision (wi::to_wide (gimple_assign_rhs2 (use_stmt)),
    6931              :                                  UNSIGNED) > narrow_prec)
    6932              :             return false;
    6933              :         }
    6934              :       else
    6935              :         return false;
    6936            5 :     }
    6937         2239 :   return true;
    6938              : }
    6939              : 
    6940              : /* True when every use of PROD reads only its low NARROW_PREC bits.  */
    6941              : 
    6942              : static bool
    6943         2236 : long_mul_only_low_half_used_p (tree prod, unsigned int narrow_prec)
    6944              : {
    6945         2236 :   auto_vec<gimple *, 4> high_uses;
    6946         2236 :   return (long_mul_high_half_uses (prod, narrow_prec, &high_uses)
    6947         4472 :           && high_uses.is_empty ());
    6948         2236 : }
    6949              : 
    6950              : /* True when STMT is res = a * b whose unsigned 2N-bit result is in a mode the
    6951              :    target cannot multiply, having neither insn nor libcall, so that expand_mult
    6952              :    would abort; set *NARROW_TYPE to the N-bit unsigned type its halves are
    6953              :    built at.  A mode the target does support is left to convert_mult_to_widen
    6954              :    and convert_mult_to_highpart.  */
    6955              : 
    6956              : static bool
    6957     88729739 : unexpandable_long_mul_p (gimple *stmt, tree *narrow_type)
    6958              : {
    6959     88729739 :   if (!is_gimple_assign (stmt) || gimple_assign_rhs_code (stmt) != MULT_EXPR)
    6960              :     return false;
    6961              : 
    6962      1479408 :   tree wide_type = TREE_TYPE (gimple_assign_lhs (stmt));
    6963      1479408 :   scalar_int_mode wide_mode;
    6964      1479408 :   if (!INTEGRAL_TYPE_P (wide_type)
    6965      1221844 :       || !TYPE_UNSIGNED (wide_type)
    6966       902558 :       || !is_a <scalar_int_mode> (TYPE_MODE (wide_type), &wide_mode)
    6967      2701252 :       || targetm.scalar_mode_supported_p (wide_mode))
    6968              :     return false;
    6969              : 
    6970         2244 :   *narrow_type
    6971         2244 :     = build_nonstandard_integer_type (TYPE_PRECISION (wide_type) / 2, 1);
    6972         2244 :   return true;
    6973              : }
    6974              : 
    6975              : static bool narrow_long_mul_low_half (gimple_stmt_iterator *);
    6976              : 
    6977              : /* OP1 and OP2 are the operands of a 2N multiply just narrowed or lowered;
    6978              :    that rewrite now reads each through an N-bit low-half cast.  An operand
    6979              :    defined by another 2N multiply can thereby become low-half-only -- narrow
    6980              :    it too, recursing through chained wide products such as (a*b)*c.  */
    6981              : 
    6982              : static void
    6983         2215 : narrow_long_mul_operands (tree op1, tree op2)
    6984              : {
    6985         6645 :   for (tree op : { op1, op2 })
    6986         4430 :     if (TREE_CODE (op) == SSA_NAME)
    6987              :       {
    6988         3903 :         gimple *def = SSA_NAME_DEF_STMT (op);
    6989         3903 :         if (is_gimple_assign (def) && gimple_assign_rhs_code (def) == MULT_EXPR)
    6990              :           {
    6991            5 :             gimple_stmt_iterator dgsi = gsi_for_stmt (def);
    6992            5 :             narrow_long_mul_low_half (&dgsi);
    6993              :           }
    6994              :       }
    6995         2215 : }
    6996              : 
    6997              : /* If the statement at *GSI is res = a * b with a 2N-bit unsigned result the
    6998              :    target cannot multiply and every use reads only the low N bits, narrow it
    6999              :    to res = (2N) ((N) a * (N) b) and return true.  The low N bits of a product
    7000              :    depend only on the low N bits of the operands, so this preserves every use;
    7001              :    the unused high half becomes zero.  match.pd's shorten rule omits this for
    7002              :    MULT_EXPR.  */
    7003              : 
    7004              : static bool
    7005       754046 : narrow_long_mul_low_half (gimple_stmt_iterator *gsi)
    7006              : {
    7007       754046 :   gimple *stmt = gsi_stmt (*gsi);
    7008       754046 :   tree narrow_type;
    7009       754046 :   if (!unexpandable_long_mul_p (stmt, &narrow_type))
    7010              :     return false;
    7011              : 
    7012         2236 :   tree lhs = gimple_assign_lhs (stmt);
    7013         2236 :   if (!long_mul_only_low_half_used_p (lhs, TYPE_PRECISION (narrow_type)))
    7014              :     return false;
    7015              : 
    7016           13 :   tree op1 = gimple_assign_rhs1 (stmt);
    7017           13 :   tree op2 = gimple_assign_rhs2 (stmt);
    7018           13 :   location_t loc = gimple_location (stmt);
    7019           13 :   gimple_seq seq = NULL;
    7020           13 :   tree a = gimple_convert (&seq, loc, narrow_type, op1);
    7021           13 :   tree b = gimple_convert (&seq, loc, narrow_type, op2);
    7022           13 :   tree np = gimple_build (&seq, loc, MULT_EXPR, narrow_type, a, b);
    7023           13 :   gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
    7024           13 :   gimple *conv = gimple_build_assign (lhs, NOP_EXPR, np);
    7025           13 :   gimple_set_location (conv, loc);
    7026           13 :   gsi_replace (gsi, conv, true);
    7027              : 
    7028           13 :   if (dump_file && (dump_flags & TDF_DETAILS))
    7029            0 :     fprintf (dump_file, "Narrowed low-half-only long multiply.\n");
    7030              : 
    7031           13 :   narrow_long_mul_operands (op1, op2);
    7032           13 :   return true;
    7033              : }
    7034              : 
    7035              : /* The 2N multiply at *GSI has had its high half synthesized elsewhere, so any
    7036              :    use left reads only its low half: narrow it in place, or remove it when it
    7037              :    has no use at all.  Removing it drops a use of each operand, so a 2N
    7038              :    multiply defining one may become low-half-only.  Narrow those operands.  */
    7039              : 
    7040              : static void
    7041         2218 : finish_long_mul_low_half (gimple_stmt_iterator *gsi)
    7042              : {
    7043         2218 :   gimple *stmt = gsi_stmt (*gsi);
    7044              : 
    7045         2218 :   if (has_zero_uses (gimple_assign_lhs (stmt)))
    7046              :     {
    7047         2202 :       tree op1 = gimple_assign_rhs1 (stmt);
    7048         2202 :       tree op2 = gimple_assign_rhs2 (stmt);
    7049         2202 :       gsi_remove (gsi, true);
    7050         2202 :       release_defs (stmt);
    7051         2202 :       narrow_long_mul_operands (op1, op2);
    7052         2202 :       return;
    7053              :     }
    7054              : 
    7055           16 :   narrow_long_mul_low_half (gsi);
    7056              : }
    7057              : 
    7058              : /* Rewrite the multiply STMT into the N-bit halves its uses read, when the
    7059              :    target can neither multiply at 2N bits nor form an N-bit high part.
    7060              :    Returns true on a rewrite, which may remove STMT.
    7061              : 
    7062              :    Runs once lower_long_mul_high_chain has been applied to every statement:
    7063              :    both rewrite products with a high half, and this one, keyed on the
    7064              :    definition rather than on a consumer, would otherwise pre-empt it.  What
    7065              :    reaches it is a product that lowering could not retire, its high half also
    7066              :    read as an operand of another product, or read alongside the low half.  A
    7067              :    product read only for its low half is left to narrow_long_mul_low_half.  */
    7068              : 
    7069              : static bool
    7070     87975693 : narrow_long_mul_halves (gimple *stmt)
    7071              : {
    7072     87975693 :   tree narrow_type;
    7073     87975693 :   if (!unexpandable_long_mul_p (stmt, &narrow_type))
    7074              :     return false;
    7075              : 
    7076              :   /* Only worth lowering where the target cannot form the N-bit high part.  */
    7077            8 :   scalar_int_mode narrow_mode;
    7078            8 :   if (!is_a <scalar_int_mode> (TYPE_MODE (narrow_type), &narrow_mode)
    7079            8 :       || can_mult_highpart_p (narrow_mode, true))
    7080              :     return false;
    7081              : 
    7082            8 :   tree lhs = gimple_assign_lhs (stmt);
    7083            8 :   auto_vec<gimple *, 4> high_uses;
    7084            8 :   if (!long_mul_high_half_uses (lhs, TYPE_PRECISION (narrow_type), &high_uses)
    7085           16 :       || high_uses.is_empty ())
    7086              :     return false;
    7087              : 
    7088            8 :   tree op1 = gimple_assign_rhs1 (stmt);
    7089            8 :   tree op2 = gimple_assign_rhs2 (stmt);
    7090            8 :   location_t loc = gimple_location (stmt);
    7091            8 :   gimple_seq seq = NULL;
    7092            8 :   tree l1, h1, l2, h2;
    7093            8 :   if (!long_mul_split_operand (&seq, loc, op1, narrow_type, &l1, &h1)
    7094            8 :       || !long_mul_split_operand (&seq, loc, op2, narrow_type, &l2, &h2))
    7095              :     return false;
    7096            8 :   tree hi = combine_long_mul_halves (&seq, loc, l1, h1, l2, h2, narrow_type);
    7097              :   /* The high part is < 2^N, so widening it back to 2N leaves every use of a
    7098              :      shift, full width or truncated, reading the same value.  */
    7099            8 :   tree hi_wide = gimple_convert (&seq, loc, TREE_TYPE (lhs), hi);
    7100            8 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    7101            8 :   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    7102              : 
    7103            8 :   unsigned int i;
    7104            8 :   gimple *shift_stmt;
    7105           24 :   FOR_EACH_VEC_ELT (high_uses, i, shift_stmt)
    7106              :     {
    7107            8 :       gimple_stmt_iterator sgsi = gsi_for_stmt (shift_stmt);
    7108            8 :       gimple *conv = gimple_build_assign (gimple_assign_lhs (shift_stmt),
    7109              :                                           hi_wide);
    7110            8 :       gimple_set_location (conv, loc);
    7111            8 :       gsi_replace (&sgsi, conv, true);
    7112              :     }
    7113              : 
    7114            8 :   if (dump_file && (dump_flags & TDF_DETAILS))
    7115            0 :     fprintf (dump_file, "Narrowed high half of long multiply.\n");
    7116              : 
    7117            8 :   finish_long_mul_low_half (&gsi);
    7118            8 :   return true;
    7119            8 : }
    7120              : 
    7121              : /* Match.pd recognizer for the long-multiply recognizer's high-part
    7122              :    emit chain.  */
    7123              : 
    7124              : extern bool gimple_long_mul_high_chain (tree, tree *, tree (*)(tree));
    7125              : 
    7126              : /* Rewrite the `long_mul_high_chain' whose tail is the statement at GSI
    7127              : 
    7128              :      wide_a    = (T_2N) op1
    7129              :      wide_b    = (T_2N) op2
    7130              :      wide_prod = wide_a * wide_b
    7131              :      hi        = wide_prod >> N
    7132              :      lhs       = (convert) hi
    7133              : 
    7134              :    to a longhand high-part synthesis at T_N precision.  Never materializes
    7135              :    T_2N in gimple, so it covers cases where the 2N mode has no expansion path
    7136              :    (e.g. the high 128 bits of a 128x128 product where 2N=OImode).  An operand
    7137              :    wider than T_N -- a shared wide product or a sign-extended cast -- is split
    7138              :    into T_N halves rather than truncated, so no high input bits are dropped.
    7139              :    Returns true on a rewrite.  */
    7140              : 
    7141              : static bool
    7142      2466195 : lower_long_mul_high_chain (gimple_stmt_iterator *gsi)
    7143              : {
    7144      2466195 :   gimple *trunc_stmt = gsi_stmt (*gsi);
    7145      2466195 :   if (!is_gimple_assign (trunc_stmt))
    7146              :     return false;
    7147              : 
    7148      2466195 :   tree narrow_lhs = gimple_assign_lhs (trunc_stmt);
    7149      2466195 :   tree ops[2];
    7150      2466195 :   if (!gimple_long_mul_high_chain (narrow_lhs, ops, NULL))
    7151              :     return false;
    7152              : 
    7153              :   /* Walk the matched chain back to the 2N multiply and take narrow_type at
    7154              :      half its precision.  */
    7155         2475 :   gimple *shift_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (trunc_stmt));
    7156         2475 :   gimple *mult_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (shift_stmt));
    7157         2475 :   unsigned int narrow_prec
    7158         2475 :     = TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (mult_stmt))) / 2;
    7159         2475 :   tree narrow_type = build_nonstandard_integer_type (narrow_prec, /*uns=*/1);
    7160         2475 :   scalar_int_mode narrow_mode;
    7161         2475 :   if (!is_a <scalar_int_mode> (TYPE_MODE (narrow_type), &narrow_mode))
    7162              :     return false;
    7163              : 
    7164              :   /* Lower only when the target cannot form the N-bit high part itself.  */
    7165         2475 :   if (can_mult_highpart_p (narrow_mode, true))
    7166              :     return false;
    7167              : 
    7168         2210 :   location_t loc = gimple_location (trunc_stmt);
    7169         2210 :   gimple_seq seq = NULL;
    7170              : 
    7171              :   /* Split each operand into N-bit halves and combine.  An operand that fits
    7172              :      N bits yields h == 0, so its cross term folds away; with both fitting
    7173              :      the combine is just a plain N-bit high part.  */
    7174         2210 :   tree l1, h1, l2, h2;
    7175         2210 :   if (!long_mul_split_operand (&seq, loc, gimple_assign_rhs1 (mult_stmt),
    7176              :                                narrow_type, &l1, &h1)
    7177         2210 :       || !long_mul_split_operand (&seq, loc, gimple_assign_rhs2 (mult_stmt),
    7178              :                                   narrow_type, &l2, &h2))
    7179              :     return false;
    7180         2210 :   tree hi = combine_long_mul_halves (&seq, loc, l1, h1, l2, h2, narrow_type);
    7181              : 
    7182              :   /* Merging the chain's truncation with a later user cast can retarget the
    7183              :      outer convert to any integral type, so convert the narrow result once
    7184              :      here (the high part is < 2^N, so the conversion preserves it).  */
    7185         2210 :   gimple *result_stmt;
    7186         2210 :   tree lhs_type = TREE_TYPE (narrow_lhs);
    7187         2210 :   if (useless_type_conversion_p (lhs_type, narrow_type))
    7188         2204 :     result_stmt = gimple_build_assign (narrow_lhs, hi);
    7189              :   else
    7190            6 :     result_stmt = gimple_build_assign (narrow_lhs, NOP_EXPR, hi);
    7191         2210 :   gimple_set_location (result_stmt, loc);
    7192         2210 :   gimple_seq_add_stmt (&seq, result_stmt);
    7193              : 
    7194         2210 :   gsi_replace_with_seq (gsi, seq, true);
    7195              : 
    7196              :   /* Clean up the shift and the 2N mult now -- LTRANS runs no DCE between
    7197              :      widening_mul and expand, and a dead 2N mult would abort expand_mult.
    7198              :      Dead upstream (T_2N) casts, if any, are harmless NOP_EXPRs and land
    7199              :      with normal DCE.  */
    7200         2210 :   if (has_zero_uses (gimple_assign_lhs (shift_stmt)))
    7201              :     {
    7202         2202 :       gimple_stmt_iterator dgsi = gsi_for_stmt (shift_stmt);
    7203         2202 :       gsi_remove (&dgsi, true);
    7204         2202 :       release_defs (shift_stmt);
    7205              :     }
    7206              : 
    7207              :   /* The mult is either dead (low half recomputed elsewhere) or now read only
    7208              :      for its low half.  */
    7209         2210 :   gimple_stmt_iterator mgsi = gsi_for_stmt (mult_stmt);
    7210         2210 :   finish_long_mul_low_half (&mgsi);
    7211              : 
    7212         2210 :   if (dump_file && (dump_flags & TDF_DETAILS))
    7213            4 :     fprintf (dump_file, "Lowered long-mul high-part chain.\n");
    7214              :   return true;
    7215              : }
    7216              : 
    7217              : /* True when pass_optimize_widening_mul will run.  Shared with the
    7218              :    forwprop long-multiply recognizer so its wide-chain emit stays
    7219              :    paired with the lowering that rescues an unsupported 2N shape.
    7220              :    The -Og pipeline (pass_all_optimizations_g) does not contain
    7221              :    pass_optimize_widening_mul at all, so -Og -fexpensive-optimizations
    7222              :    must not enable the emit: the unlowered 2N multiply would reach
    7223              :    expand as an unexpandable mode (e.g. OImode) and ICE.
    7224              :    -fdisable-tree-widening_mul is not observed.  */
    7225              : 
    7226              : bool
    7227      1081132 : optimize_widening_mul_active_p (void)
    7228              : {
    7229      1081132 :   return flag_expensive_optimizations && optimize && !optimize_debug;
    7230              : }
    7231              : 
    7232              : /* Find integer multiplications where the operands are extended from
    7233              :    smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
    7234              :    or MULT_HIGHPART_EXPR where appropriate.  */
    7235              : 
    7236              : namespace {
    7237              : 
    7238              : const pass_data pass_data_optimize_widening_mul =
    7239              : {
    7240              :   GIMPLE_PASS, /* type */
    7241              :   "widening_mul", /* name */
    7242              :   OPTGROUP_NONE, /* optinfo_flags */
    7243              :   TV_TREE_WIDEN_MUL, /* tv_id */
    7244              :   PROP_ssa, /* properties_required */
    7245              :   0, /* properties_provided */
    7246              :   0, /* properties_destroyed */
    7247              :   0, /* todo_flags_start */
    7248              :   TODO_update_ssa, /* todo_flags_finish */
    7249              : };
    7250              : 
    7251              : class pass_optimize_widening_mul : public gimple_opt_pass
    7252              : {
    7253              : public:
    7254       294587 :   pass_optimize_widening_mul (gcc::context *ctxt)
    7255       589174 :     : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt)
    7256              :   {}
    7257              : 
    7258              :   /* opt_pass methods: */
    7259      1062413 :   bool gate (function *) final override
    7260              :     {
    7261      1062413 :       return optimize_widening_mul_active_p ();
    7262              :     }
    7263              : 
    7264              :   unsigned int execute (function *) final override;
    7265              : 
    7266              : }; // class pass_optimize_widening_mul
    7267              : 
    7268              : /* Walker class to perform the transformation in reverse dominance order. */
    7269              : 
    7270              : class math_opts_dom_walker : public dom_walker
    7271              : {
    7272              : public:
    7273              :   /* Constructor, CFG_CHANGED is a pointer to a boolean flag that will be set
    7274              :      if walking modidifes the CFG.  */
    7275              : 
    7276       983322 :   math_opts_dom_walker (bool *cfg_changed_p)
    7277      1966644 :     : dom_walker (CDI_DOMINATORS), m_last_result_set (),
    7278       983322 :       m_cfg_changed_p (cfg_changed_p) {}
    7279              : 
    7280              :   /* The actual actions performed in the walk.  */
    7281              : 
    7282              :   void after_dom_children (basic_block) final override;
    7283              : 
    7284              :   /* Set of results of chains of multiply and add statement combinations that
    7285              :      were not transformed into FMAs because of active deferring.  */
    7286              :   hash_set<tree> m_last_result_set;
    7287              : 
    7288              :   /* Pointer to a flag of the user that needs to be set if CFG has been
    7289              :      modified.  */
    7290              :   bool *m_cfg_changed_p;
    7291              : };
    7292              : 
    7293              : void
    7294     10458165 : math_opts_dom_walker::after_dom_children (basic_block bb)
    7295              : {
    7296     10458165 :   gimple_stmt_iterator gsi;
    7297              : 
    7298     10458165 :   fma_deferring_state fma_state (param_avoid_fma_max_bits > 0
    7299     10561745 :                                  && param_widening_mul_defer_fma);
    7300              : 
    7301     14762824 :   for (gphi_iterator psi_next, psi = gsi_start_phis (bb); !gsi_end_p (psi);
    7302      4304659 :        psi = psi_next)
    7303              :     {
    7304      4304659 :       psi_next = psi;
    7305      4304659 :       gsi_next (&psi_next);
    7306              : 
    7307      4304659 :       gimple_stmt_iterator gsi = gsi_after_labels (bb);
    7308      4304659 :       gphi *phi = psi.phi ();
    7309              : 
    7310      4304659 :       if (match_saturation_add (&gsi, phi)
    7311      4304640 :           || match_saturation_sub (&gsi, phi)
    7312      4304592 :           || match_saturation_trunc (&gsi, phi)
    7313      4304592 :           || match_saturation_mul (&gsi, phi)
    7314      8609251 :           || match_spaceship (&gsi, phi))
    7315          179 :         remove_phi_node (&psi, /* release_lhs_p */ false);
    7316              :     }
    7317              : 
    7318     97340749 :   for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
    7319              :     {
    7320     86882584 :       gimple *stmt = gsi_stmt (gsi);
    7321     86882584 :       enum tree_code code;
    7322              : 
    7323     86882584 :       if (is_gimple_assign (stmt))
    7324              :         {
    7325     21720069 :           code = gimple_assign_rhs_code (stmt);
    7326     21720069 :           switch (code)
    7327              :             {
    7328       754025 :             case MULT_EXPR:
    7329       754025 :               if (narrow_long_mul_low_half (&gsi))
    7330              :                 break;
    7331       754025 :               if (!convert_mult_to_widen (stmt, &gsi)
    7332       745175 :                   && !convert_expand_mult_copysign (stmt, &gsi)
    7333      1499157 :                   && convert_mult_to_fma (stmt,
    7334              :                                           gimple_assign_rhs1 (stmt),
    7335              :                                           gimple_assign_rhs2 (stmt),
    7336              :                                           &fma_state))
    7337              :                 {
    7338        16517 :                   gsi_remove (&gsi, true);
    7339        16517 :                   release_defs (stmt);
    7340        16517 :                   continue;
    7341              :                 }
    7342       737508 :               match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
    7343       737508 :               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
    7344       737508 :               break;
    7345              : 
    7346      2313396 :             case PLUS_EXPR:
    7347      2313396 :               if (match_saturation_add_with_assign (&gsi,
    7348              :                                                     as_a<gassign *> (stmt)))
    7349              :                 break;
    7350              :               /* fall-through  */
    7351      2622021 :             case MINUS_EXPR:
    7352      2622021 :               if (!match_unsigned_saturation_sub (&gsi,
    7353              :                                                   as_a<gassign *> (stmt))
    7354      2622021 :                   && !convert_plusminus_to_widen (&gsi, stmt, code))
    7355              :                 {
    7356      2621896 :                   match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
    7357      2621896 :                   if (gsi_stmt (gsi) == stmt)
    7358      2615957 :                     match_uaddc_usubc (&gsi, stmt, code);
    7359              :                 }
    7360              :               break;
    7361              : 
    7362        39266 :             case BIT_NOT_EXPR:
    7363        39266 :               if (match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p))
    7364          239 :                 continue;
    7365              :               break;
    7366              : 
    7367        57146 :             case TRUNC_MOD_EXPR:
    7368        57146 :               convert_to_divmod (as_a<gassign *> (stmt));
    7369        57146 :               break;
    7370              : 
    7371       173600 :             case RSHIFT_EXPR:
    7372       173600 :               convert_mult_to_highpart (as_a<gassign *> (stmt), &gsi);
    7373       173600 :               break;
    7374              : 
    7375       192811 :             case BIT_IOR_EXPR:
    7376       192811 :               match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt));
    7377       192811 :               match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
    7378       192811 :               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
    7379              :               /* fall-through  */
    7380       224302 :             case BIT_XOR_EXPR:
    7381       224302 :               match_uaddc_usubc (&gsi, stmt, code);
    7382       224302 :               break;
    7383              : 
    7384       326953 :             case EQ_EXPR:
    7385       326953 :             case NE_EXPR:
    7386       326953 :             case LE_EXPR:
    7387       326953 :             case GT_EXPR:
    7388       326953 :               match_single_bit_test (&gsi, stmt);
    7389       326953 :               break;
    7390              : 
    7391       350544 :             case COND_EXPR:
    7392       350544 :             case BIT_AND_EXPR:
    7393       350544 :               match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
    7394       350544 :               break;
    7395              : 
    7396      2466282 :             case NOP_EXPR:
    7397      2466282 :               match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt));
    7398      2466282 :               match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
    7399      2466282 :               match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
    7400              :               /* fall-through  */
    7401      2466297 :             case CONVERT_EXPR:
    7402              :               /* The long-multiply recognizer's high-part emit ends in an
    7403              :                  outer convert.  If the trailing cast+mult+shift+cast
    7404              :                  chain has no expansion strategy at the 2N width, lower
    7405              :                  the whole chain to a longhand high-part at narrow
    7406              :                  precision.  */
    7407      2466297 :               if (gsi_stmt (gsi) == stmt
    7408      2466297 :                   && lower_long_mul_high_chain (&gsi))
    7409         2210 :                 continue;
    7410              :               break;
    7411              : 
    7412          193 :             default:;
    7413              :             }
    7414              :         }
    7415     65162515 :       else if (is_gimple_call (stmt))
    7416              :         {
    7417      4901463 :           switch (gimple_call_combined_fn (stmt))
    7418              :             {
    7419          129 :             case CFN_COND_MUL:
    7420          129 :               if (convert_mult_to_fma (stmt,
    7421              :                                        gimple_call_arg (stmt, 1),
    7422              :                                        gimple_call_arg (stmt, 2),
    7423              :                                        &fma_state,
    7424              :                                        gimple_call_arg (stmt, 0)))
    7425              : 
    7426              :                 {
    7427           84 :                   gsi_remove (&gsi, true);
    7428           84 :                   release_defs (stmt);
    7429           84 :                   continue;
    7430              :                 }
    7431              :               break;
    7432              : 
    7433            0 :             case CFN_COND_LEN_MUL:
    7434            0 :               if (convert_mult_to_fma (stmt,
    7435              :                                        gimple_call_arg (stmt, 1),
    7436              :                                        gimple_call_arg (stmt, 2),
    7437              :                                        &fma_state,
    7438              :                                        gimple_call_arg (stmt, 0),
    7439              :                                        gimple_call_arg (stmt, 4),
    7440              :                                        gimple_call_arg (stmt, 5)))
    7441              : 
    7442              :                 {
    7443            0 :                   gsi_remove (&gsi, true);
    7444            0 :                   release_defs (stmt);
    7445            0 :                   continue;
    7446              :                 }
    7447              :               break;
    7448              : 
    7449      3730212 :             case CFN_LAST:
    7450      3730212 :               cancel_fma_deferring (&fma_state);
    7451      3730212 :               break;
    7452              : 
    7453              :             default:
    7454              :               break;
    7455              :             }
    7456              :         }
    7457     60261052 :       else if (gimple_code (stmt) == GIMPLE_COND)
    7458              :         {
    7459      4219657 :           match_single_bit_test (&gsi, stmt);
    7460      4219657 :           optimize_spaceship (as_a <gcond *> (stmt));
    7461              :         }
    7462     86863534 :       gsi_next (&gsi);
    7463              :     }
    7464     10458165 :   if (fma_state.m_deferring_p
    7465      7657243 :       && fma_state.m_initial_phi)
    7466              :     {
    7467          361 :       gcc_checking_assert (fma_state.m_last_result);
    7468          361 :       if (!last_fma_candidate_feeds_initial_phi (&fma_state,
    7469              :                                                  &m_last_result_set))
    7470          264 :         cancel_fma_deferring (&fma_state);
    7471              :       else
    7472           97 :         m_last_result_set.add (fma_state.m_last_result);
    7473              :     }
    7474     10458165 : }
    7475              : 
    7476              : 
    7477              : unsigned int
    7478       983322 : pass_optimize_widening_mul::execute (function *fun)
    7479              : {
    7480       983322 :   bool cfg_changed = false;
    7481              : 
    7482       983322 :   memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
    7483       983322 :   calculate_dominance_info (CDI_DOMINATORS);
    7484       983322 :   renumber_gimple_stmt_uids (cfun);
    7485              : 
    7486       983322 :   long_mul_phi_halves = new hash_map<tree, long_mul_halves>;
    7487              : 
    7488       983322 :   math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    7489              : 
    7490              :   /* A 2N multiply the target cannot expand would abort expand_mult.  Every
    7491              :      statement has been through the lowerings above, so one left here matched
    7492              :      none of them.  */
    7493       983322 :   basic_block bb;
    7494     10458165 :   FOR_EACH_BB_FN (bb, fun)
    7495    106925379 :     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    7496              :       {
    7497     87975693 :         gimple *stmt = gsi_stmt (gsi);
    7498     87975693 :         gsi_next (&gsi);
    7499     87975693 :         narrow_long_mul_halves (stmt);
    7500              :       }
    7501              : 
    7502      1966644 :   delete long_mul_phi_halves;
    7503       983322 :   long_mul_phi_halves = NULL;
    7504              : 
    7505       983322 :   statistics_counter_event (fun, "widening multiplications inserted",
    7506              :                             widen_mul_stats.widen_mults_inserted);
    7507       983322 :   statistics_counter_event (fun, "widening maccs inserted",
    7508              :                             widen_mul_stats.maccs_inserted);
    7509       983322 :   statistics_counter_event (fun, "fused multiply-adds inserted",
    7510              :                             widen_mul_stats.fmas_inserted);
    7511       983322 :   statistics_counter_event (fun, "divmod calls inserted",
    7512              :                             widen_mul_stats.divmod_calls_inserted);
    7513       983322 :   statistics_counter_event (fun, "highpart multiplications inserted",
    7514              :                             widen_mul_stats.highpart_mults_inserted);
    7515              : 
    7516       983322 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    7517              : }
    7518              : 
    7519              : } // anon namespace
    7520              : 
    7521              : gimple_opt_pass *
    7522       294587 : make_pass_optimize_widening_mul (gcc::context *ctxt)
    7523              : {
    7524       294587 :   return new pass_optimize_widening_mul (ctxt);
    7525              : }
        

Generated by: LCOV version 2.4-beta

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