LCOV - code coverage report
Current view: top level - gcc - tree-ssa-phiopt.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.4 % 2236 2133
Test Date: 2026-08-22 16:33:35 Functions: 100.0 % 54 54
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Optimization of PHI nodes by converting them into straightline code.
       2              :    Copyright (C) 2004-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              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "insn-codes.h"
      25              : #include "rtl.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "cfghooks.h"
      29              : #include "tree-pass.h"
      30              : #include "ssa.h"
      31              : #include "tree-ssa.h"
      32              : #include "optabs-tree.h"
      33              : #include "insn-config.h"
      34              : #include "gimple-pretty-print.h"
      35              : #include "fold-const.h"
      36              : #include "stor-layout.h"
      37              : #include "cfganal.h"
      38              : #include "gimple-iterator.h"
      39              : #include "tree-cfg.h"
      40              : #include "tree-dfa.h"
      41              : #include "domwalk.h"
      42              : #include "cfgloop.h"
      43              : #include "tree-data-ref.h"
      44              : #include "tree-scalar-evolution.h"
      45              : #include "tree-inline.h"
      46              : #include "case-cfn-macros.h"
      47              : #include "tree-eh.h"
      48              : #include "gimple-fold.h"
      49              : #include "internal-fn.h"
      50              : #include "gimple-range.h"
      51              : #include "gimple-match.h"
      52              : #include "dbgcnt.h"
      53              : #include "tree-ssa-propagate.h"
      54              : #include "tree-ssa-dce.h"
      55              : #include "tree-ssa-loop-niter.h"
      56              : #include "gimple-predict.h"
      57              : #include "alias.h"
      58              : 
      59              : /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
      60              : 
      61              : static gphi *
      62      3552452 : single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
      63              : {
      64      3552452 :   gimple_stmt_iterator i;
      65      3552452 :   gphi *phi = NULL;
      66      5276881 :   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
      67              :     {
      68      4296432 :       gphi *p = as_a <gphi *> (gsi_stmt (i));
      69              :       /* If the PHI arguments are equal then we can skip this PHI. */
      70      4296432 :       if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
      71      4296432 :                                        gimple_phi_arg_def (p, e1->dest_idx)))
      72       249998 :         continue;
      73              : 
      74              :       /* Punt on virtual phis with different arguments from the edges.  */
      75      8092868 :       if (virtual_operand_p (gimple_phi_result (p)))
      76              :         return NULL;
      77              : 
      78              :       /* If we already have a PHI that has the two edge arguments are
      79              :          different, then return it is not a singleton for these PHIs. */
      80      1732627 :       if (phi)
      81              :         return NULL;
      82              : 
      83              :       phi = p;
      84              :     }
      85              :   return phi;
      86              : }
      87              : 
      88              : /* Replace PHI node element whose edge is E in block BB with variable NEW.
      89              :    Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
      90              :    is known to have two edges, one of which must reach BB).  */
      91              : 
      92              : static void
      93        98098 : replace_phi_edge_with_variable (basic_block cond_block,
      94              :                                 edge e, gphi *phi, tree new_tree,
      95              :                                 bitmap dce_ssa_names = nullptr)
      96              : {
      97        98098 :   basic_block bb = gimple_bb (phi);
      98        98098 :   gimple_stmt_iterator gsi;
      99        98098 :   tree phi_result = gimple_phi_result (phi);
     100        98098 :   bool deleteboth = false;
     101              : 
     102              :   /* Duplicate range info if they are the only things setting the target PHI.
     103              :      This is needed as later on, the new_tree will be replacing
     104              :      The assignment of the PHI.
     105              :      For an example:
     106              :      bb1:
     107              :      _4 = min<a_1, 255>
     108              :      goto bb2
     109              : 
     110              :      # RANGE [-INF, 255]
     111              :      a_3 = PHI<_4(1)>
     112              :      bb3:
     113              : 
     114              :      use(a_3)
     115              :      And _4 gets propagated into the use of a_3 and losing the range info.
     116              :      This can't be done for more than 2 incoming edges as the propagation
     117              :      won't happen.
     118              :      The new_tree needs to be defined in the same basic block as the conditional.  */
     119        98098 :   if (TREE_CODE (new_tree) == SSA_NAME
     120        98079 :       && EDGE_COUNT (gimple_bb (phi)->preds) == 2
     121        64098 :       && INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
     122        58915 :       && !SSA_NAME_RANGE_INFO (new_tree)
     123        58809 :       && SSA_NAME_RANGE_INFO (phi_result)
     124        36306 :       && gimple_bb (SSA_NAME_DEF_STMT (new_tree)) == cond_block
     125       134404 :       && dbg_cnt (phiopt_edge_range))
     126        36306 :     duplicate_ssa_name_range_info (new_tree, phi_result);
     127              : 
     128              :   /* Change the PHI argument to new.  */
     129        98098 :   SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
     130              : 
     131              :   /* Remove the empty basic block.  */
     132        98098 :   edge edge_to_remove = NULL, keep_edge = NULL;
     133        98098 :   if (EDGE_SUCC (cond_block, 0)->dest == bb)
     134              :     {
     135        33711 :       edge_to_remove = EDGE_SUCC (cond_block, 1);
     136        33711 :       keep_edge = EDGE_SUCC (cond_block, 0);
     137              :     }
     138        64387 :   else if (EDGE_SUCC (cond_block, 1)->dest == bb)
     139              :     {
     140              :       edge_to_remove = EDGE_SUCC (cond_block, 0);
     141              :       keep_edge = EDGE_SUCC (cond_block, 1);
     142              :     }
     143         1359 :   else if ((keep_edge = find_edge (cond_block, e->src)))
     144              :     {
     145         1359 :       basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
     146         1359 :       basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
     147       100816 :       if (single_pred_p (bb1) && single_pred_p (bb2)
     148         2718 :           && single_succ_p (bb1) && single_succ_p (bb2)
     149         2718 :           && empty_block_p (bb1) && empty_block_p (bb2))
     150              :         deleteboth = true;
     151              :     }
     152              :   else
     153            0 :     gcc_unreachable ();
     154              : 
     155              :   /* If we are removing the cond on a loop exit,
     156              :      reset number of iteration information of the loop. */
     157        98098 :   if (loop_exits_from_bb_p (cond_block->loop_father, cond_block))
     158              :     {
     159            0 :       auto loop = cond_block->loop_father;
     160            0 :       free_numbers_of_iterations_estimates (loop);
     161            0 :       loop->any_upper_bound = false;
     162            0 :       loop->any_likely_upper_bound = false;
     163              :     }
     164              : 
     165        98098 :   if (edge_to_remove && EDGE_COUNT (edge_to_remove->dest->preds) == 1)
     166              :     {
     167        85379 :       e->flags |= EDGE_FALLTHRU;
     168        85379 :       e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
     169        85379 :       e->probability = profile_probability::always ();
     170        85379 :       delete_basic_block (edge_to_remove->dest);
     171              : 
     172              :       /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
     173        85379 :       gsi = gsi_last_bb (cond_block);
     174        85379 :       gsi_remove (&gsi, true);
     175              :     }
     176        12719 :   else if (deleteboth)
     177              :     {
     178         1357 :       basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
     179         1357 :       basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
     180              : 
     181         1357 :       edge newedge = redirect_edge_and_branch (keep_edge, bb);
     182              : 
     183              :       /* The new edge should be the same. */
     184         1357 :       gcc_assert (newedge == keep_edge);
     185              : 
     186         1357 :       keep_edge->flags |= EDGE_FALLTHRU;
     187         1357 :       keep_edge->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
     188         1357 :       keep_edge->probability = profile_probability::always ();
     189              : 
     190              :       /* Copy the edge's phi entry from the old one. */
     191         1357 :       copy_phi_arg_into_existing_phi (e, keep_edge);
     192              : 
     193              :       /* Delete the old 2 empty basic blocks */
     194         1357 :       delete_basic_block (bb1);
     195         1357 :       delete_basic_block (bb2);
     196              : 
     197              :       /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
     198         1357 :       gsi = gsi_last_bb (cond_block);
     199         1357 :       gsi_remove (&gsi, true);
     200              :     }
     201              :   else
     202              :     {
     203              :       /* If there are other edges into the middle block make
     204              :          CFG cleanup deal with the edge removal to avoid
     205              :          updating dominators here in a non-trivial way.  */
     206        22724 :       gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_block));
     207        11362 :       if (keep_edge->flags & EDGE_FALSE_VALUE)
     208         7475 :         gimple_cond_make_false (cond);
     209         3887 :       else if (keep_edge->flags & EDGE_TRUE_VALUE)
     210         3887 :         gimple_cond_make_true (cond);
     211              :     }
     212              : 
     213        98098 :   if (dce_ssa_names)
     214        96106 :     simple_dce_from_worklist (dce_ssa_names);
     215              : 
     216        98098 :   statistics_counter_event (cfun, "Replace PHI with variable", 1);
     217              : 
     218        98098 :   if (dump_file && (dump_flags & TDF_DETAILS))
     219           29 :     fprintf (dump_file,
     220              :               "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
     221              :               cond_block->index,
     222              :               bb->index);
     223        98098 : }
     224              : 
     225              : /* Returns true if the OPERANDS (OPCOUNTED) defined from DEF_STMT is profitable to move
     226              :    to the usage into the basic block MERGE where the new statement
     227              :    will be located.  */
     228              : static bool
     229        67615 : is_factor_profitable (gimple *def_stmt, basic_block merge, tree *operands, unsigned opcount)
     230              : {
     231              :   /* The defining statement should be conditional.  */
     232        67615 :   if (dominated_by_p (CDI_DOMINATORS, merge,
     233        67615 :                       gimple_bb (def_stmt)))
     234              :     return false;
     235              : 
     236              :   /* We should not increase the live range of arg
     237              :      across too many statements or calls.  */
     238        63710 :   gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
     239        63710 :   gsi_next_nondebug (&gsi);
     240              : 
     241              :   /* Skip past nops and predicates. */
     242       127926 :   while (!gsi_end_p (gsi)
     243        64216 :          && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
     244         9288 :              || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
     245          506 :     gsi_next_nondebug (&gsi);
     246              : 
     247              :   /* If the defining statement is at the end of the bb, then it is
     248              :      always profitable to be to move.  */
     249        63710 :   if (gsi_end_p (gsi))
     250              :     return true;
     251              : 
     252              :   /* If there are a few (non-call/asm) statements between
     253              :      the old defining statement and end of the bb, then
     254              :      the live range of operands will increase enough.  */
     255         8782 :   int max_statements = param_phiopt_factor_max_stmts_live;
     256         8782 :   bool stmts_extending_ok = true;
     257              : 
     258        25230 :   while (!gsi_end_p (gsi))
     259              :     {
     260        17338 :       gimple *stmt = gsi_stmt (gsi);
     261        17338 :       auto gcode = gimple_code (stmt);
     262              :       /* Skip over NOPs and predicts. */
     263        17352 :       if (gcode == GIMPLE_NOP
     264        17338 :           || gcode == GIMPLE_PREDICT)
     265              :         {
     266           14 :           gsi_next_nondebug (&gsi);
     267           14 :           continue;
     268              :         }
     269              :       /* Non-assigns will extend the live range too much.  */
     270        17324 :       if (gcode != GIMPLE_ASSIGN)
     271              :         {
     272              :           stmts_extending_ok = false;
     273              :           break;
     274              :         }
     275        17044 :       max_statements --;
     276        17044 :       if (max_statements == 0)
     277              :         {
     278              :           stmts_extending_ok = false;
     279              :           break;
     280              :         }
     281        16434 :       gsi_next_nondebug (&gsi);
     282              :   }
     283         8782 :   if (stmts_extending_ok)
     284              :     return true;
     285              : 
     286              :   /* Loop over all of the operands to see if all are used after anyways.  */
     287         1237 :   for (unsigned i = 0; i < opcount; i++)
     288              :     {
     289          920 :       tree arg = operands[i];
     290              :       /* If the arg is invariant, then there is
     291              :          no extending of the live range. */
     292          920 :       if (is_gimple_min_invariant (arg))
     293          304 :         continue;
     294              : 
     295              :       /* Otherwise, the arg needs to be a ssa name. */
     296          616 :       if (TREE_CODE (arg) != SSA_NAME)
     297          573 :         return false;
     298              : 
     299              :       /* Check if the uses of arg is dominated by merge block, this is a quick and
     300              :          rough estimate if arg is still alive at the merge bb.  */
     301              :       /* FIXME: extend to a more complete live range detection.  */
     302          616 :       use_operand_p use_p;
     303          616 :       imm_use_iterator iter;
     304          616 :       bool usedafter = false;
     305         2791 :       FOR_EACH_IMM_USE_FAST (use_p, iter, arg)
     306              :         {
     307         2218 :           gimple *use_stmt = USE_STMT (use_p);
     308         2218 :           if (is_gimple_debug (use_stmt))
     309          216 :             continue;
     310         2002 :           basic_block use_bb = gimple_bb (use_stmt);
     311         2002 :           if (dominated_by_p (CDI_DOMINATORS, merge, use_bb))
     312              :             {
     313              :               usedafter = true;
     314              :               break;
     315              :             }
     316          616 :         }
     317          616 :       if (!usedafter)
     318              :         return false;
     319              :     }
     320              :   return true;
     321              : }
     322              : 
     323              : /* PR66726: Factor operations out of COND_EXPR.  If the arguments of the PHI
     324              :    stmt are Unary operator, factor out the operation and perform the operation
     325              :    to the result of PHI stmt.  COND_STMT is the controlling predicate.
     326              :    Return true if the operation was factored out; false otherwise.  */
     327              : 
     328              : static bool
     329      3094548 : factor_out_conditional_operation (edge e0, edge e1, basic_block merge,
     330              :                                   gphi *phi, gimple *cond_stmt,
     331              :                                   bool early_p)
     332              : {
     333      3094548 :   gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL;
     334      3094548 :   tree temp, result;
     335      3094548 :   gphi *newphi;
     336      3094548 :   gimple_stmt_iterator gsi, gsi_for_def;
     337      3094548 :   location_t locus = gimple_location (phi);
     338      3094548 :   gimple_match_op arg0_op, arg1_op;
     339              : 
     340              :   /* We should only get here if the phi had two arguments.  */
     341      3094548 :   gcc_assert (gimple_phi_num_args (phi) == 2);
     342              : 
     343              :   /* Virtual operands are never handled. */
     344      6189096 :   if (virtual_operand_p (gimple_phi_result (phi)))
     345              :     return false;
     346              : 
     347      1354814 :   tree arg0 = gimple_phi_arg_def (phi, e0->dest_idx);
     348      1354814 :   tree arg1 = gimple_phi_arg_def (phi, e1->dest_idx);
     349      1354814 :   location_t narg0_loc = gimple_location (phi);
     350      1354814 :   location_t narg1_loc = gimple_location (phi);
     351      1354814 :   if (gimple_phi_arg_location (phi, e0->dest_idx) != UNKNOWN_LOCATION)
     352      1137387 :     narg0_loc = gimple_phi_arg_location (phi, e0->dest_idx);
     353      1354814 :   if (gimple_phi_arg_location (phi, e1->dest_idx) != UNKNOWN_LOCATION)
     354       956540 :     narg1_loc = gimple_phi_arg_location (phi, e1->dest_idx);
     355              : 
     356      1354814 :   gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
     357              : 
     358              :   /* Arguments that are the same don't have anything to be
     359              :      done to them. */
     360      1354814 :   if (operand_equal_for_phi_arg_p (arg0, arg1))
     361              :     return false;
     362              : 
     363              :   /* First canonicalize to simplify tests.  */
     364      1354634 :   if (TREE_CODE (arg0) != SSA_NAME)
     365              :     {
     366       252661 :       std::swap (arg0, arg1);
     367       252661 :       std::swap (e0, e1);
     368              :     }
     369              : 
     370      1354634 :   if (TREE_CODE (arg0) != SSA_NAME
     371      1234893 :       || (TREE_CODE (arg1) != SSA_NAME
     372       501848 :           && TREE_CODE (arg1) != INTEGER_CST))
     373              :     return false;
     374              : 
     375              :   /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is
     376              :      an unary operation.  */
     377      1197797 :   arg0_def_stmt = SSA_NAME_DEF_STMT (arg0);
     378      1197797 :   if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
     379              :     return false;
     380              : 
     381              :   /* Check to make sure none of the operands are in abnormal phis.  */
     382       619406 :   if (arg0_op.operands_occurs_in_abnormal_phi ())
     383              :    return false;
     384              : 
     385       619406 :   tree new_arg0;
     386       619406 :   tree new_arg1;
     387       619406 :   int opnum = -1;
     388              : 
     389              :   /* If arg0 have > 1 use, then this transformation actually increases
     390              :      the number of expressions evaluated at runtime.  */
     391       619406 :   if (!has_single_use (arg0))
     392              :     return false;
     393       506438 :   if (gimple_has_location (arg0_def_stmt))
     394       467640 :     narg0_loc = gimple_location (arg0_def_stmt);
     395              : 
     396       506438 :   if (TREE_CODE (arg1) == SSA_NAME)
     397              :     {
     398              :       /* Check if arg1 is an SSA_NAME.  */
     399       330602 :       arg1_def_stmt = SSA_NAME_DEF_STMT (arg1);
     400       330602 :       if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
     401              :         return false;
     402       172409 :       if (arg1_op.code != arg0_op.code)
     403              :         return false;
     404        51685 :       if (arg1_op.num_ops != arg0_op.num_ops)
     405              :         return false;
     406        51669 :       if (arg1_op.operands_occurs_in_abnormal_phi ())
     407              :         return false;
     408              : 
     409              :       /* For the complex expression, don't factor
     410              :          out, that will confuse the uninitializing
     411              :          warnings.  */
     412        51669 :       if (arg1_op.code == COMPLEX_EXPR)
     413              :         return false;
     414              : 
     415              :       /* If arg1 have > 1 use, then this transformation actually increases
     416              :          the number of expressions evaluated at runtime.  */
     417        51554 :       if (!has_single_use (arg1))
     418              :         return false;
     419              : 
     420        39606 :       opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1);
     421        39606 :       if (opnum == -1)
     422              :         return false;
     423              : 
     424              :       /* Check to make sure extending the lifetimes of all operands is ok.  */
     425        13411 :       if (!is_factor_profitable (arg0_def_stmt, merge,
     426              :                                  arg0_op.ops, arg0_op.num_ops))
     427              :         return false;
     428        12446 :       if (!is_factor_profitable (arg1_def_stmt, merge,
     429              :                                  arg1_op.ops, arg1_op.num_ops))
     430              :         return false;
     431              : 
     432              :       /* If this was a division and the operand is the divisor
     433              :          and either divisor was a constant, don't factor out
     434              :          the division; dividing by an explicit constant can be
     435              :          expanded better than without an constant.
     436              :          FIXME: maybe isel could undo this case.  */
     437         9663 :       if (int_divide_or_mod_p (arg1_op.code)
     438          400 :           && opnum == 1
     439           42 :           && (poly_int_tree_p (new_arg0)
     440            0 :               || poly_int_tree_p (new_arg1)))
     441              :         return false;
     442              : 
     443              :       /* For early phiopt, don't factor out constants for pointer plus.
     444              :          BOS pass does not like that factoring.  */
     445         4495 :       if (early_p && arg1_op.code == POINTER_PLUS_EXPR
     446          198 :           && opnum == 1
     447          185 :           && TREE_CODE (new_arg0) != SSA_NAME
     448         9641 :           && TREE_CODE (new_arg1) != SSA_NAME)
     449              :         return false;
     450              : 
     451              :       /* BIT_FIELD_REF and BIT_INSERT_EXPR can't be factored out for non-0 operands
     452              :          as the other operands require constants. */
     453         9602 :       if ((arg1_op.code == BIT_FIELD_REF
     454         9572 :            || arg1_op.code == BIT_INSERT_EXPR)
     455         9669 :           && opnum != 0)
     456              :         return false;
     457              : 
     458              :       /* It is not profitability to factor out vec_perm with
     459              :          constant masks (operand 2).  The target might not support it
     460              :          and that might be invalid to do as such. Also with constants
     461              :          masks, the number of elements of the mask type does not need
     462              :          to match the number of elements of other operands and can be
     463              :          arbitrary integral vector type so factoring that out can't work.
     464              :          Note in the case where one mask is a constant and the other is not,
     465              :          the check for compatible types will reject the case the
     466              :          constant mask has the incompatible type.  */
     467         9524 :       if (arg1_op.code == VEC_PERM_EXPR && opnum == 2
     468          103 :           && TREE_CODE (new_arg0) == VECTOR_CST
     469         9627 :           && TREE_CODE (new_arg1) == VECTOR_CST)
     470              :         return false;
     471              : 
     472         9440 :       if (gimple_has_location (arg1_def_stmt))
     473         9182 :         narg1_loc = gimple_location (arg1_def_stmt);
     474              : 
     475              :       /* Chose the location for the new statement if the phi location is unknown.  */
     476         9440 :       if (locus == UNKNOWN_LOCATION)
     477              :         {
     478         9440 :           if (narg0_loc == UNKNOWN_LOCATION
     479         9440 :               && narg1_loc != UNKNOWN_LOCATION)
     480              :             locus = narg1_loc;
     481         9440 :           else if (narg0_loc != UNKNOWN_LOCATION
     482         9440 :                    && narg1_loc == UNKNOWN_LOCATION)
     483           51 :             locus = narg0_loc;
     484              :         }
     485              :     }
     486       175836 :   else if (arg0_op.num_ops != 1)
     487              :     return false;
     488              :   else
     489              :     {
     490        51434 :       new_arg0 = arg0_op.ops[0];
     491        51434 :       opnum = 0;
     492              :       /* For constants only handle if the phi was the only one. */
     493        51434 :       if (single_non_singleton_phi_for_edges (phi_nodes (merge), e0, e1) == NULL)
     494              :         return false;
     495              :       /* TODO: handle more than just casts here. */
     496        38200 :       if (!gimple_assign_cast_p (arg0_def_stmt))
     497              :         return false;
     498        31776 :       if (!is_factor_profitable (arg0_def_stmt, merge, arg0_op.ops, arg0_op.num_ops))
     499              :         return false;
     500              : 
     501              :       /* If arg1 is an INTEGER_CST, fold it to new type if it fits, or else
     502              :          if the bits will not be modified during the conversion, except for
     503              :          boolean types whose precision is not 1 (see int_fits_type_p).  */
     504        62115 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (new_arg0))
     505        61860 :           || !(int_fits_type_p (arg1, TREE_TYPE (new_arg0))
     506         1587 :                || (TYPE_PRECISION (TREE_TYPE (new_arg0))
     507         1587 :                    == TYPE_PRECISION (TREE_TYPE (arg1))
     508          687 :                    && (TREE_CODE (TREE_TYPE (new_arg0)) != BOOLEAN_TYPE
     509            0 :                        || TYPE_PRECISION (TREE_TYPE (new_arg0)) == 1))))
     510              :         return false;
     511              : 
     512              :       /* For the INTEGER_CST case, we are just moving the
     513              :          conversion from one place to another, which can often
     514              :          hurt as the conversion moves further away from the
     515              :          statement that computes the value.  So, perform this
     516              :          only if new_arg0 is an operand of COND_STMT, or
     517              :          if arg0_def_stmt is the only non-debug stmt in
     518              :          its basic block, because then it is possible this
     519              :          could enable further optimizations (minmax replacement
     520              :          etc.).  See PR71016.
     521              :          Note no-op conversions don't have this issue as
     522              :          it will not generate any zero/sign extend in that case.  */
     523        29909 :       if ((TYPE_PRECISION (TREE_TYPE (new_arg0))
     524        29909 :            != TYPE_PRECISION (TREE_TYPE (arg1)))
     525        14394 :           && new_arg0 != gimple_cond_lhs (cond_stmt)
     526        13698 :           && new_arg0 != gimple_cond_rhs (cond_stmt)
     527        43601 :           && gimple_bb (arg0_def_stmt) == e0->src)
     528              :         {
     529        13692 :           gsi = gsi_for_stmt (arg0_def_stmt);
     530        13692 :           gsi_prev_nondebug (&gsi);
     531              :           /* Ignore nops, predicates and labels. */
     532        27396 :           while (!gsi_end_p (gsi)
     533        13704 :                   && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
     534              :                       || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT
     535              :                       || gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL))
     536           12 :             gsi_prev_nondebug (&gsi);
     537              : 
     538        13692 :           if (!gsi_end_p (gsi))
     539              :             {
     540        10280 :               gimple *stmt = gsi_stmt (gsi);
     541        10280 :               if (gassign *assign = dyn_cast <gassign *> (stmt))
     542              :                 {
     543         9668 :                   tree lhs = gimple_assign_lhs (assign);
     544         9668 :                   tree lhst = TREE_TYPE (lhs);
     545         9668 :                   enum tree_code ass_code
     546         9668 :                     = gimple_assign_rhs_code (assign);
     547         9668 :                   if (ass_code != MAX_EXPR && ass_code != MIN_EXPR
     548              :                       /* Conversions from boolean like types is ok
     549              :                          as `a?1:b` and `a?0:b` will always simplify
     550              :                          to `a & b` or `a | b`.
     551              :                          See PR 116890.  */
     552         9668 :                       && !(INTEGRAL_TYPE_P (lhst)
     553         9213 :                            && TYPE_UNSIGNED (lhst)
     554         6904 :                            && TYPE_PRECISION (lhst) == 1))
     555              :                     return false;
     556         4664 :                   if (lhs != gimple_assign_rhs1 (arg0_def_stmt))
     557              :                     return false;
     558         4622 :                   gsi_prev_nondebug (&gsi);
     559         4622 :                   if (!gsi_end_p (gsi))
     560              :                     return false;
     561              :                 }
     562              :               else
     563              :                 return false;
     564              :             }
     565              :         }
     566        19875 :       new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
     567              : 
     568              :       /* Drop the overflow that fold_convert might add. */
     569        19875 :       if (TREE_OVERFLOW (new_arg1))
     570            0 :         new_arg1 = drop_tree_overflow (new_arg1);
     571              : 
     572              :       /* The locus of the new statement is arg0 defining statement. */
     573        19875 :       if (gimple_has_location (arg0_def_stmt))
     574        19423 :         locus = gimple_location (arg0_def_stmt);
     575              :     }
     576              : 
     577              :   /* If types of new_arg0 and new_arg1 are different bailout.  */
     578        29315 :   if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1)))
     579              :     return false;
     580              : 
     581              :   /* Create a new PHI stmt.  */
     582        28302 :   result = gimple_phi_result (phi);
     583        28302 :   temp = make_ssa_name (TREE_TYPE (new_arg0), NULL);
     584              : 
     585        28302 :   gimple_match_op new_op = arg0_op;
     586              : 
     587              :   /* Create the operation stmt if possible and insert it.  */
     588        28302 :   new_op.ops[opnum] = temp;
     589        28302 :   gimple_seq seq = NULL;
     590        28302 :   result = maybe_push_res_to_seq (&new_op, &seq, result);
     591              : 
     592              :   /* If we can't create the new statement, release the temp name
     593              :      and return back.  */
     594        28302 :   if (!result)
     595              :     {
     596          256 :       release_ssa_name (temp);
     597          256 :       return false;
     598              :     }
     599              : 
     600        28046 :   if (locus != UNKNOWN_LOCATION)
     601        19470 :     annotate_all_with_location (seq, locus);
     602        28046 :   gsi = gsi_after_labels (gimple_bb (phi));
     603        28046 :   gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
     604              : 
     605        28046 :   newphi = create_phi_node (temp, gimple_bb (phi));
     606              : 
     607        28046 :   if (dump_file && (dump_flags & TDF_DETAILS))
     608              :     {
     609           35 :       fprintf (dump_file, "PHI ");
     610           35 :       print_generic_expr (dump_file, gimple_phi_result (phi));
     611           35 :       fprintf (dump_file,
     612              :                " changed to factor operation out from COND_EXPR.\n");
     613           35 :       fprintf (dump_file, "New stmt with OPERATION that defines ");
     614           35 :       print_generic_expr (dump_file, result);
     615           35 :       fprintf (dump_file, ".\n");
     616              :     }
     617              : 
     618              :   /* Remove the old operation(s) that has single use.  */
     619        28046 :   gsi_for_def = gsi_for_stmt (arg0_def_stmt);
     620        28046 :   gsi_remove (&gsi_for_def, true);
     621        28046 :   release_defs (arg0_def_stmt);
     622              : 
     623        28046 :   if (arg1_def_stmt)
     624              :     {
     625         8171 :       gsi_for_def = gsi_for_stmt (arg1_def_stmt);
     626         8171 :       gsi_remove (&gsi_for_def, true);
     627         8171 :       release_defs (arg1_def_stmt);
     628              :     }
     629              : 
     630        28046 :   add_phi_arg (newphi, new_arg0, e0, narg0_loc);
     631        28046 :   add_phi_arg (newphi, new_arg1, e1, narg1_loc);
     632              : 
     633              :   /* Remove the original PHI stmt.  */
     634        28046 :   gsi = gsi_for_stmt (phi);
     635        28046 :   remove_phi_node (&gsi, false);
     636              : 
     637        28046 :   statistics_counter_event (cfun, "factored out operation", 1);
     638              : 
     639        28046 :   return true;
     640              : }
     641              : 
     642              : 
     643              : /* Return TRUE if SEQ/OP pair should be allowed during early phiopt.
     644              :    Currently this is to allow MIN/MAX and ABS/NEGATE and constants.  */
     645              : static bool
     646       180337 : phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
     647              : {
     648              :   /* Don't allow functions. */
     649       180337 :   if (!op.code.is_tree_code ())
     650              :     return false;
     651       180276 :   tree_code code = (tree_code)op.code;
     652              : 
     653              :   /* For non-empty sequence, only allow one statement
     654              :      a MIN/MAX and an original MIN/MAX.  */
     655       180276 :   if (!gimple_seq_empty_p (seq))
     656              :     {
     657       148634 :       if (code == MIN_EXPR || code == MAX_EXPR)
     658              :         {
     659       151666 :           if (!gimple_seq_singleton_p (seq))
     660              :             return false;
     661              : 
     662            3 :           gimple *stmt = gimple_seq_first_stmt (seq);
     663              :           /* Only allow assignments.  */
     664            3 :           if (!is_gimple_assign (stmt))
     665              :             return false;
     666            3 :           code = gimple_assign_rhs_code (stmt);
     667            3 :           return code == MIN_EXPR || code == MAX_EXPR;
     668              :         }
     669              :       return false;
     670              :     }
     671              : 
     672        31642 :   switch (code)
     673              :     {
     674              :       case MIN_EXPR:
     675              :       case MAX_EXPR:
     676              :       case ABS_EXPR:
     677              :       case ABSU_EXPR:
     678              :       case NEGATE_EXPR:
     679              :       case SSA_NAME:
     680              :         return true;
     681              :       case INTEGER_CST:
     682              :       case REAL_CST:
     683              :       case VECTOR_CST:
     684              :       case FIXED_CST:
     685              :         return true;
     686              :       default:
     687              :         return false;
     688              :     }
     689              : }
     690              : 
     691              : /* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
     692              :    Return NULL if nothing can be simplified or the resulting simplified value
     693              :    with parts pushed if EARLY_P was true. Also rejects non allowed tree code
     694              :    if EARLY_P is set.
     695              :    Takes the comparison from COMP_STMT and two args, ARG0 and ARG1 and tries
     696              :    to simplify CMP ? ARG0 : ARG1.
     697              :    Also try to simplify (!CMP) ? ARG1 : ARG0 if the non-inverse failed.  */
     698              : static tree
     699       546980 : gimple_simplify_phiopt (bool early_p, tree type, gimple *comp_stmt,
     700              :                         tree arg0, tree arg1,
     701              :                         gimple_seq *seq)
     702              : {
     703       546980 :   gimple_seq seq1 = NULL;
     704       546980 :   enum tree_code comp_code = gimple_cond_code (comp_stmt);
     705       546980 :   location_t loc = gimple_location (comp_stmt);
     706       546980 :   tree cmp0 = gimple_cond_lhs (comp_stmt);
     707       546980 :   tree cmp1 = gimple_cond_rhs (comp_stmt);
     708              :   /* To handle special cases like floating point comparison, it is easier and
     709              :      less error-prone to build a tree and gimplify it on the fly though it is
     710              :      less efficient.
     711              :      Don't use fold_build2 here as that might create (bool)a instead of just
     712              :      "a != 0".  */
     713       546980 :   tree cond = build2_loc (loc, comp_code, boolean_type_node,
     714              :                           cmp0, cmp1);
     715              : 
     716       546980 :   if (dump_file && (dump_flags & TDF_FOLDING))
     717              :     {
     718            1 :       fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
     719            1 :       print_generic_expr (dump_file, cond);
     720            1 :       fprintf (dump_file, " ? ");
     721            1 :       print_generic_expr (dump_file, arg0);
     722            1 :       fprintf (dump_file, " : ");
     723            1 :       print_generic_expr (dump_file, arg1);
     724            1 :       fprintf (dump_file, "\n");
     725              :     }
     726              : 
     727       546980 :   gimple_match_op op (gimple_match_cond::UNCOND,
     728       546980 :                       COND_EXPR, type, cond, arg0, arg1);
     729              : 
     730       546980 :   if (op.resimplify (&seq1, follow_all_ssa_edges))
     731              :     {
     732       163594 :       bool allowed = !early_p || phiopt_early_allow (seq1, op);
     733       163594 :       tree result = maybe_push_res_to_seq (&op, &seq1);
     734       163594 :       if (dump_file && (dump_flags & TDF_FOLDING))
     735              :         {
     736            1 :           fprintf (dump_file, "\nphiopt match-simplify back:\n");
     737            1 :           if (seq1)
     738            0 :             print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
     739            1 :           fprintf (dump_file, "result: ");
     740            1 :           if (result)
     741            1 :             print_generic_expr (dump_file, result);
     742              :           else
     743            0 :             fprintf (dump_file, " (none)");
     744            1 :           fprintf (dump_file, "\n");
     745            1 :           if (!allowed)
     746            0 :             fprintf (dump_file, "rejected because early\n");
     747              :         }
     748              :       /* Early we want only to allow some generated tree codes. */
     749       163594 :       if (allowed && result)
     750              :         {
     751        86661 :           if (loc != UNKNOWN_LOCATION)
     752        86192 :             annotate_all_with_location (seq1, loc);
     753        86661 :           gimple_seq_add_seq_without_update (seq, seq1);
     754        86661 :           return result;
     755              :         }
     756              :     }
     757       460319 :   gimple_seq_discard (seq1);
     758       460319 :   seq1 = NULL;
     759              : 
     760              :   /* Try the inverted comparison, that is !COMP ? ARG1 : ARG0. */
     761       460319 :   comp_code = invert_tree_comparison (comp_code, HONOR_NANS (cmp0));
     762              : 
     763       460319 :   if (comp_code == ERROR_MARK)
     764              :     return NULL;
     765              : 
     766       443278 :   cond = build2_loc (loc,
     767              :                      comp_code, boolean_type_node,
     768              :                      cmp0, cmp1);
     769              : 
     770       443278 :   if (dump_file && (dump_flags & TDF_FOLDING))
     771              :     {
     772            0 :       fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
     773            0 :       print_generic_expr (dump_file, cond);
     774            0 :       fprintf (dump_file, " ? ");
     775            0 :       print_generic_expr (dump_file, arg1);
     776            0 :       fprintf (dump_file, " : ");
     777            0 :       print_generic_expr (dump_file, arg0);
     778            0 :       fprintf (dump_file, "\n");
     779              :     }
     780              : 
     781       443278 :   gimple_match_op op1 (gimple_match_cond::UNCOND,
     782       443278 :                        COND_EXPR, type, cond, arg1, arg0);
     783              : 
     784       443278 :   if (op1.resimplify (&seq1, follow_all_ssa_edges))
     785              :     {
     786        80163 :       bool allowed = !early_p || phiopt_early_allow (seq1, op1);
     787        80163 :       tree result = maybe_push_res_to_seq (&op1, &seq1);
     788        80163 :       if (dump_file && (dump_flags & TDF_FOLDING))
     789              :         {
     790            0 :           fprintf (dump_file, "\nphiopt match-simplify back:\n");
     791            0 :           if (seq1)
     792            0 :             print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
     793            0 :           fprintf (dump_file, "result: ");
     794            0 :           if (result)
     795            0 :             print_generic_expr (dump_file, result);
     796              :           else
     797            0 :             fprintf (dump_file, " (none)");
     798            0 :           fprintf (dump_file, "\n");
     799            0 :           if (!allowed)
     800            0 :             fprintf (dump_file, "rejected because early\n");
     801              :         }
     802              :       /* Early we want only to allow some generated tree codes. */
     803        80163 :       if (allowed && result)
     804              :         {
     805         5401 :           if (loc != UNKNOWN_LOCATION)
     806         5401 :             annotate_all_with_location (seq1, loc);
     807         5401 :           gimple_seq_add_seq_without_update (seq, seq1);
     808         5401 :           return result;
     809              :         }
     810              :     }
     811       437877 :   gimple_seq_discard (seq1);
     812              : 
     813       437877 :   return NULL;
     814              : }
     815              : 
     816              : /* one_feeding_comparison_into_p returns true if BB has one comparison
     817              :    statement and it sets STMT to that statement.  Note the comparison can
     818              :    be trapping too.  */
     819              : static bool
     820         1200 : one_feeding_comparison_into_p (basic_block bb,
     821              :                                gimple *phi,
     822              :                                gassign *&assign)
     823              : {
     824         1200 :   assign = nullptr;
     825         1200 :   gimple *stmt = nullptr;
     826              : 
     827         1200 :   if (empty_block_p (bb))
     828              :     return false;
     829              : 
     830         1182 :   if (!single_pred_p (bb))
     831              :     return false;
     832              : 
     833         1174 :   if (!gimple_seq_empty_p (phi_nodes (bb)))
     834              :     return false;
     835              : 
     836         1174 :   gimple_stmt_iterator gsi;
     837         1174 :   gsi = gsi_start_nondebug_after_labels_bb (bb);
     838         2350 :   while (!gsi_end_p (gsi))
     839              :     {
     840         1978 :       gimple *s = gsi_stmt (gsi);
     841         1978 :       gsi_next_nondebug (&gsi);
     842              :       /* Skip over Predict and nop statements. */
     843         1978 :       if (gimple_code (s) == GIMPLE_PREDICT
     844         1978 :           || gimple_code (s) == GIMPLE_NOP)
     845            2 :         continue;
     846              :       /* If there is more one statement return false. */
     847         1976 :       if (stmt)
     848              :         return false;
     849              :       stmt = s;
     850              :     }
     851              : 
     852          372 :   if (!stmt)
     853              :     return false;
     854              : 
     855          744 :   if (gimple_vuse (stmt))
     856              :     return false;
     857              : 
     858          366 :   gassign *a = dyn_cast<gassign*>(stmt);
     859          366 :   if (!a || TREE_CODE_CLASS (gimple_assign_rhs_code (a)) != tcc_comparison)
     860              :     return false;
     861              : 
     862          366 :   tree lhs = gimple_assign_lhs (a);
     863              : 
     864          366 :   gimple *use_stmt;
     865          366 :   use_operand_p use_p;
     866              :   /* Allow only a statement which feeds into the other stmt.  */
     867          366 :   if (!lhs || TREE_CODE (lhs) != SSA_NAME
     868          366 :       || !single_imm_use (lhs, &use_p, &use_stmt)
     869          732 :       || use_stmt != phi)
     870              :     return false;
     871              : 
     872              :   // Don't handle non-call exceptions
     873          366 :   if (stmt_could_throw_p (cfun, a))
     874              :     return false;
     875              : 
     876          354 :   assign = a;
     877          354 :   return true;
     878              : }
     879              : 
     880              : /* empty_bb_or_one_feeding_into_p returns true if bb was empty basic block
     881              :    or it has one cheap preparation statement that feeds into the PHI
     882              :    statement and it sets STMT to that statement. */
     883              : static bool
     884       899847 : empty_bb_or_one_feeding_into_p (basic_block bb,
     885              :                                 gimple *phi,
     886              :                                 gimple *&stmt)
     887              : {
     888       899847 :   stmt = nullptr;
     889       899847 :   gimple *stmt_to_move = nullptr;
     890       899847 :   tree lhs;
     891              : 
     892       899847 :   if (empty_block_p (bb))
     893              :     return true;
     894              : 
     895       481949 :   if (!single_pred_p (bb))
     896              :     return false;
     897              : 
     898              :   /* The middle bb cannot have phi nodes as we don't
     899              :      move those assignments yet. */
     900       468725 :   if (!gimple_seq_empty_p (phi_nodes (bb)))
     901              :     return false;
     902              : 
     903       468705 :   gimple_stmt_iterator gsi;
     904              : 
     905       468705 :   gsi = gsi_start_nondebug_after_labels_bb (bb);
     906       940493 :   while (!gsi_end_p (gsi))
     907              :     {
     908       687398 :       gimple *s = gsi_stmt (gsi);
     909       687398 :       gsi_next_nondebug (&gsi);
     910              :       /* Skip over Predict and nop statements. */
     911       687398 :       if (gimple_code (s) == GIMPLE_PREDICT
     912       687398 :           || gimple_code (s) == GIMPLE_NOP)
     913         3083 :         continue;
     914              :       /* If there is more one statement return false. */
     915       684315 :       if (stmt_to_move)
     916              :         return false;
     917              :       stmt_to_move = s;
     918              :     }
     919              : 
     920              :   /* The only statement here was a Predict or a nop statement
     921              :      so return true. */
     922       253095 :   if (!stmt_to_move)
     923              :     return true;
     924              : 
     925       506190 :   if (gimple_vuse (stmt_to_move))
     926              :     return false;
     927              : 
     928       172592 :   if (gimple_could_trap_p (stmt_to_move)
     929       172592 :       || gimple_has_side_effects (stmt_to_move))
     930              :     return false;
     931              : 
     932       167159 :   ssa_op_iter it;
     933       167159 :   tree use;
     934       368769 :   FOR_EACH_SSA_TREE_OPERAND (use, stmt_to_move, it, SSA_OP_USE)
     935       202270 :     if (ssa_name_maybe_undef_p (use))
     936              :       return false;
     937              : 
     938              :   /* Allow assignments but allow some builtin/internal calls.
     939              :      As const calls don't match any of the above, yet they could
     940              :      still have some side-effects - they could contain
     941              :      gimple_could_trap_p statements, like floating point
     942              :      exceptions or integer division by zero.  See PR70586.
     943              :      FIXME: perhaps gimple_has_side_effects or gimple_could_trap_p
     944              :      should handle this.
     945              :      Allow some known builtin/internal calls that are known not to
     946              :      trap: logical functions (e.g. bswap and bit counting). */
     947       166499 :   if (!is_gimple_assign (stmt_to_move))
     948              :     {
     949         5790 :       if (!is_gimple_call (stmt_to_move))
     950              :         return false;
     951         5539 :       combined_fn cfn = gimple_call_combined_fn (stmt_to_move);
     952         5539 :       switch (cfn)
     953              :         {
     954              :         default:
     955              :           return false;
     956         4620 :         CASE_CFN_BSWAP:
     957         4620 :         CASE_CFN_BITREVERSE:
     958         4620 :         CASE_CFN_FFS:
     959         4620 :         CASE_CFN_PARITY:
     960         4620 :         CASE_CFN_POPCOUNT:
     961         4620 :         CASE_CFN_CLZ:
     962         4620 :         CASE_CFN_CTZ:
     963         4620 :         case CFN_BUILT_IN_CLRSB:
     964         4620 :         case CFN_BUILT_IN_CLRSBL:
     965         4620 :         case CFN_BUILT_IN_CLRSBLL:
     966         4620 :           lhs = gimple_call_lhs (stmt_to_move);
     967         4620 :           break;
     968              :         }
     969              :     }
     970              :   else
     971       160709 :     lhs = gimple_assign_lhs (stmt_to_move);
     972              : 
     973       165329 :   gimple *use_stmt;
     974       165329 :   use_operand_p use_p;
     975              : 
     976              :   /* Allow only a statement which feeds into the other stmt.  */
     977       165329 :   if (!lhs || TREE_CODE (lhs) != SSA_NAME
     978       165329 :       || !single_imm_use (lhs, &use_p, &use_stmt)
     979       330653 :       || use_stmt != phi)
     980              :     return false;
     981              : 
     982       165324 :   stmt = stmt_to_move;
     983       165324 :   return true;
     984              : }
     985              : 
     986              : /* Move STMT to before GSI and insert its defining
     987              :    name into INSERTED_EXPRS bitmap.
     988              :    Also rewrite its if it might be undefined when unconditionalized.  */
     989              : static void
     990       192212 : move_stmt (gimple *stmt, gimple_stmt_iterator *gsi, auto_bitmap &inserted_exprs)
     991              : {
     992       192212 :   if (!stmt)
     993       185995 :     return;
     994         6217 :   if (dump_file && (dump_flags & TDF_DETAILS))
     995              :     {
     996            9 :       fprintf (dump_file, "statement un-sinked:\n");
     997            9 :       print_gimple_stmt (dump_file, stmt, 0,
     998              :                          TDF_VOPS|TDF_MEMSYMS);
     999              :     }
    1000              : 
    1001         6217 :   tree name = gimple_get_lhs (stmt);
    1002              :   // Mark the name to be renamed if there is one.
    1003         6217 :   bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
    1004         6217 :   gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt);
    1005         6217 :   gsi_move_before (&gsi1, gsi, GSI_NEW_STMT);
    1006         6217 :   reset_flow_sensitive_info (name);
    1007              : 
    1008              :   /* Rewrite some code which might be undefined when
    1009              :      unconditionalized. */
    1010         6217 :   if (gimple_needing_rewrite_undefined (stmt))
    1011         1146 :     rewrite_to_defined_unconditional (gsi);
    1012              : }
    1013              : 
    1014              : /* RAII style class to temporarily remove flow sensitive
    1015              :    from ssa names defined by a gimple statement.  */
    1016              : class auto_flow_sensitive
    1017              : {
    1018              : public:
    1019              :   auto_flow_sensitive (gimple *s);
    1020              :   ~auto_flow_sensitive ();
    1021              : private:
    1022              :   auto_vec<std::pair<tree, flow_sensitive_info_storage>, 2> stack;
    1023              : };
    1024              : 
    1025              : /* Constructor for auto_flow_sensitive. Saves
    1026              :    off the ssa names' flow sensitive information
    1027              :    that was defined by gimple statement S and
    1028              :    resets it to be non-flow based ones. */
    1029              : 
    1030      1093960 : auto_flow_sensitive::auto_flow_sensitive (gimple *s)
    1031              : {
    1032      1093960 :   if (!s)
    1033       937675 :     return;
    1034       156285 :   ssa_op_iter it;
    1035       156285 :   tree def;
    1036       312570 :   FOR_EACH_SSA_TREE_OPERAND (def, s, it, SSA_OP_DEF)
    1037              :     {
    1038       156285 :       flow_sensitive_info_storage storage;
    1039       156285 :       storage.save_and_clear (def);
    1040       156285 :       stack.safe_push (std::make_pair (def, storage));
    1041              :     }
    1042              : }
    1043              : 
    1044              : /* Deconstructor, restores the flow sensitive information
    1045              :    for the SSA names that had been saved off.  */
    1046              : 
    1047      1093960 : auto_flow_sensitive::~auto_flow_sensitive ()
    1048              : {
    1049      3438165 :   for (auto p : stack)
    1050       156285 :     p.second.restore (p.first);
    1051      1093960 : }
    1052              : 
    1053              : /* Returns true if BB contains an user provided predictor
    1054              :    (PRED_HOT_LABEL/PRED_COLD_LABEL).  */
    1055              : 
    1056              : static bool
    1057         6382 : contains_hot_cold_predict (basic_block bb)
    1058              : {
    1059         6382 :   gimple_stmt_iterator gsi;
    1060         6382 :   gsi = gsi_start_nondebug_after_labels_bb (bb);
    1061         8924 :   for (; !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
    1062              :     {
    1063         2543 :       gimple *s = gsi_stmt (gsi);
    1064         2543 :       if (gimple_code (s) != GIMPLE_PREDICT)
    1065            2 :         continue;
    1066         2541 :       auto predict = gimple_predict_predictor (s);
    1067         2541 :       if (predict == PRED_HOT_LABEL
    1068         2541 :           || predict == PRED_COLD_LABEL)
    1069              :         return true;
    1070              :     }
    1071              :   return false;
    1072              : }
    1073              : 
    1074              : /*  The function match_simplify_replacement does the main work of doing the
    1075              :     replacement using match and simplify.  Return true if the replacement is done.
    1076              :     Otherwise return false.
    1077              :     BB is the basic block where the replacement is going to be done on.  ARG0
    1078              :     is argument 0 from PHI.  Likewise for ARG1.  */
    1079              : 
    1080              : static bool
    1081       868186 : match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
    1082              :                             basic_block middle_bb_alt,
    1083              :                             edge e0, edge e1, gphi *phi,
    1084              :                             tree arg0, tree arg1, bool early_p,
    1085              :                             bool threeway_p)
    1086              : {
    1087       868186 :   gimple *stmt;
    1088       868186 :   gimple_stmt_iterator gsi;
    1089       868186 :   edge true_edge, false_edge;
    1090       868186 :   gimple_seq seq = NULL;
    1091       868186 :   tree result;
    1092       868186 :   gimple *stmt_to_move = NULL;
    1093       868186 :   gimple *stmt_to_move_alt = NULL;
    1094       868186 :   tree arg_true, arg_false;
    1095              : 
    1096              :   /* Special case A ? B : B as this will always simplify to B. */
    1097       868186 :   if (operand_equal_for_phi_arg_p (arg0, arg1))
    1098              :     return false;
    1099              : 
    1100              :   /* If the basic block only has a cheap preparation statement,
    1101              :      allow it and move it once the transformation is done. */
    1102       868186 :   if (!empty_bb_or_one_feeding_into_p (middle_bb, phi, stmt_to_move))
    1103              :     return false;
    1104              : 
    1105       565655 :   if (threeway_p
    1106       565655 :       && middle_bb != middle_bb_alt
    1107       565655 :       && !empty_bb_or_one_feeding_into_p (middle_bb_alt, phi,
    1108              :                                           stmt_to_move_alt))
    1109              :     return false;
    1110              : 
    1111              :   /* Do not make conditional undefs unconditional.  */
    1112       551561 :   if ((TREE_CODE (arg0) == SSA_NAME
    1113       290787 :        && ssa_name_maybe_undef_p (arg0))
    1114       842030 :       || (TREE_CODE (arg1) == SSA_NAME
    1115       242503 :           && ssa_name_maybe_undef_p (arg1)))
    1116              :     return false;
    1117              : 
    1118              :     /* At this point we know we have a GIMPLE_COND with two successors.
    1119              :      One successor is BB, the other successor is an empty block which
    1120              :      falls through into BB.
    1121              : 
    1122              :      There is a single PHI node at the join point (BB).
    1123              : 
    1124              :      So, given the condition COND, and the two PHI arguments, match and simplify
    1125              :      can happen on (COND) ? arg0 : arg1. */
    1126              : 
    1127       546980 :   stmt = last_nondebug_stmt (cond_bb);
    1128              : 
    1129              :   /* We need to know which is the true edge and which is the false
    1130              :      edge so that we know when to invert the condition below.  */
    1131       546980 :   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
    1132              : 
    1133              :   /* Forward the edges over the middle basic block.  */
    1134       546980 :   if (true_edge->dest == middle_bb)
    1135       353154 :     true_edge = EDGE_SUCC (true_edge->dest, 0);
    1136       546980 :   if (false_edge->dest == middle_bb)
    1137       193826 :     false_edge = EDGE_SUCC (false_edge->dest, 0);
    1138              : 
    1139              :   /* When THREEWAY_P then e1 will point to the edge of the final transition
    1140              :      from middle-bb to end.  */
    1141       546980 :   if (true_edge == e0)
    1142              :     {
    1143       353154 :       if (!threeway_p)
    1144       336158 :         gcc_assert (false_edge == e1);
    1145              :       arg_true = arg0;
    1146              :       arg_false = arg1;
    1147              :     }
    1148              :   else
    1149              :     {
    1150       193826 :       gcc_assert (false_edge == e0);
    1151       193826 :       if (!threeway_p)
    1152       193375 :         gcc_assert (true_edge == e1);
    1153              :       arg_true = arg1;
    1154              :       arg_false = arg0;
    1155              :     }
    1156              : 
    1157       546980 :   tree type = TREE_TYPE (gimple_phi_result (phi));
    1158       546980 :   {
    1159       546980 :     auto_flow_sensitive s1(stmt_to_move);
    1160       546980 :     auto_flow_sensitive s_alt(stmt_to_move_alt);
    1161              : 
    1162       546980 :     result = gimple_simplify_phiopt (early_p, type, stmt,
    1163              :                                      arg_true, arg_false,
    1164              :                                     &seq);
    1165       546980 :   }
    1166              : 
    1167              :   /* For early phiopt, we don't want to lose user generated predictors
    1168              :      if the phiopt is converting `if (a)` into `a` as that might
    1169              :      be jump threaded later on so we want to keep around the
    1170              :      predictors.  */
    1171       546980 :   if (early_p && result && TREE_CODE (result) == SSA_NAME)
    1172              :     {
    1173        28667 :       bool check_it = false;
    1174        28667 :       tree cmp0 = gimple_cond_lhs (stmt);
    1175        28667 :       tree cmp1 = gimple_cond_rhs (stmt);
    1176        28667 :       if (result == cmp0 || result == cmp1)
    1177              :         check_it = true;
    1178        22673 :       else if (gimple_seq_singleton_p (seq))
    1179              :         {
    1180        22538 :           gimple *stmt = gimple_seq_first_stmt (seq);
    1181        22538 :           if (is_gimple_assign (stmt)
    1182        22538 :               && result == gimple_assign_lhs (stmt)
    1183        45076 :               && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
    1184              :                    == tcc_comparison)
    1185              :             check_it = true;
    1186              :         }
    1187              :       if (!check_it)
    1188              :         ;
    1189         5994 :       else if (contains_hot_cold_predict (middle_bb))
    1190              :         return false;
    1191         5993 :       else if (threeway_p
    1192              :                && middle_bb != middle_bb_alt
    1193         5993 :                && contains_hot_cold_predict (middle_bb_alt))
    1194              :         return false;
    1195              :     }
    1196              : 
    1197       546972 :   if (!result)
    1198              :     {
    1199              :       /* If we don't get back a MIN/MAX_EXPR still make sure the expression
    1200              :          stays in a form to be recognized by ISA that map to IEEE x > y ? x : y
    1201              :          semantics (that's not IEEE max semantics).  */
    1202       454918 :       if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
    1203              :         return false;
    1204        17098 :       if (stmt_to_move || stmt_to_move_alt)
    1205              :         return false;
    1206        14159 :       tree_code cmp = gimple_cond_code (stmt);
    1207        14159 :       if (cmp != LT_EXPR && cmp != LE_EXPR
    1208        14159 :           && cmp != GT_EXPR && cmp != GE_EXPR)
    1209              :         return false;
    1210         6888 :       tree lhs = gimple_cond_lhs (stmt);
    1211         6888 :       tree rhs = gimple_cond_rhs (stmt);
    1212              :       /* `lhs CMP rhs ? lhs : rhs` or `lhs CMP rhs ? rhs : lhs`
    1213              :          are only acceptable case here.  */
    1214         6888 :       if ((!operand_equal_for_phi_arg_p (lhs, arg_false)
    1215         2676 :            || !operand_equal_for_phi_arg_p (rhs, arg_true))
    1216         6966 :           && (!operand_equal_for_phi_arg_p (rhs, arg_false)
    1217         1609 :                || !operand_equal_for_phi_arg_p (lhs, arg_true)))
    1218              :         return false;
    1219         4045 :       seq = nullptr;
    1220         4045 :       result = gimple_build (&seq, cmp, boolean_type_node, lhs, rhs);
    1221         4045 :       result = gimple_build (&seq, COND_EXPR, type, result,
    1222              :                              arg_true, arg_false);
    1223         4045 :       statistics_counter_event (cfun, "Non-IEEE FP MIN/MAX PHI replacement",
    1224              :                                 1);
    1225              :     }
    1226        96106 :   if (dump_file && (dump_flags & TDF_FOLDING))
    1227            1 :     fprintf (dump_file, "accepted the phiopt match-simplify.\n");
    1228              : 
    1229        96106 :   auto_bitmap exprs_maybe_dce;
    1230              : 
    1231              :   /* Mark the cond statements' lhs/rhs as maybe dce.  */
    1232        96106 :   if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
    1233        96106 :       && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_lhs (stmt)))
    1234        90615 :     bitmap_set_bit (exprs_maybe_dce,
    1235        90615 :                     SSA_NAME_VERSION (gimple_cond_lhs (stmt)));
    1236        96106 :   if (TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME
    1237        96106 :       && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_rhs (stmt)))
    1238        28547 :     bitmap_set_bit (exprs_maybe_dce,
    1239        28547 :                     SSA_NAME_VERSION (gimple_cond_rhs (stmt)));
    1240              : 
    1241        96106 :   gsi = gsi_last_bb (cond_bb);
    1242              :   /* Insert the sequence generated from gimple_simplify_phiopt.  */
    1243        96106 :   if (seq)
    1244              :     {
    1245              :       // Mark the lhs of the new statements maybe for dce
    1246        88177 :       mark_lhs_in_seq_for_dce (exprs_maybe_dce, seq);
    1247        88177 :       gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
    1248              :     }
    1249              : 
    1250              :   /* If there was a statement to move, move it to right before
    1251              :      the original conditional.  */
    1252        96106 :   move_stmt (stmt_to_move, &gsi, exprs_maybe_dce);
    1253        96106 :   move_stmt (stmt_to_move_alt, &gsi, exprs_maybe_dce);
    1254              : 
    1255        96106 :   replace_phi_edge_with_variable (cond_bb, e1, phi, result, exprs_maybe_dce);
    1256              : 
    1257              :   /* Add Statistic here even though replace_phi_edge_with_variable already
    1258              :      does it as we want to be able to count when match-simplify happens vs
    1259              :      the others.  */
    1260        96106 :   statistics_counter_event (cfun, "match-simplify PHI replacement", 1);
    1261              : 
    1262              :   /* Note that we optimized this PHI.  */
    1263        96106 :   return true;
    1264        96106 : }
    1265              : 
    1266              : /*  The function comparison_combine tries to handle cases like:
    1267              :     if (a CMP0 b)
    1268              :       d = a CMP1 b;
    1269              :     PHI<d, [0,1]>
    1270              :     This has to be seperately as `a CMP1 b` might be trapping and
    1271              :     match_simplify_replacement does not handle trapping statements.
    1272              :     Returns true if a replacement happens.  */
    1273              : 
    1274              : static bool
    1275       772080 : comparison_combine (basic_block cond_bb, basic_block middle_bb,
    1276              :                     basic_block middle_bb_alt,
    1277              :                     edge e0, edge e1, gphi *phi,
    1278              :                     tree arg0, tree arg1, bool threeway_p)
    1279              : {
    1280       772080 :   gcond *stmt;
    1281       772080 :   gimple_stmt_iterator gsi;
    1282       772080 :   edge true_edge, false_edge;
    1283       772080 :   tree arg_true, arg_false;
    1284              : 
    1285       772080 :   if (!types_compatible_p (boolean_type_node, TREE_TYPE (arg0)))
    1286              :     return false;
    1287              : 
    1288              :   /* Do not make conditional undefs unconditional.  */
    1289       118738 :   if ((TREE_CODE (arg0) == SSA_NAME
    1290        86086 :        && ssa_name_maybe_undef_p (arg0))
    1291       204824 :       || (TREE_CODE (arg1) == SSA_NAME
    1292        19239 :           && ssa_name_maybe_undef_p (arg1)))
    1293              :     return false;
    1294              : 
    1295       118719 :   stmt = as_a<gcond*>(last_nondebug_stmt (cond_bb));
    1296              : 
    1297              :   // Handle only floating point types as they only trap.
    1298              :   // The match and simplify will handle the non-trapping case.
    1299       118719 :   if (!FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))))
    1300              :     return false;
    1301              : 
    1302              :   /* Needs to be PHI<[1,0],arg1> PHI<arg0,[1,0]>.  */
    1303         5473 :   if (((!integer_onep (arg0) && !integer_zerop (arg0))
    1304         1213 :         || TREE_CODE (arg1) != SSA_NAME)
    1305         5608 :       && ((!integer_onep (arg1) && !integer_zerop (arg1))
    1306         2365 :            || TREE_CODE (arg0) != SSA_NAME))
    1307              :     return false;
    1308              : 
    1309         1188 :   gassign *other_cmp = nullptr;
    1310         1188 :   if (!one_feeding_comparison_into_p (middle_bb, phi, other_cmp))
    1311              :     {
    1312          836 :       if (!threeway_p || middle_bb == middle_bb_alt)
    1313              :         return false;
    1314           12 :       if (!empty_block_p (middle_bb))
    1315              :         return false;
    1316           12 :       if (!one_feeding_comparison_into_p (middle_bb_alt, phi, other_cmp))
    1317              :         return false;
    1318              :     }
    1319          352 :   else if (threeway_p
    1320          352 :            && middle_bb != middle_bb_alt
    1321          352 :            && !empty_block_p (middle_bb_alt))
    1322              :     return false;
    1323              :  
    1324              :   /* We need to know which is the true edge and which is the false
    1325              :      edge so that we know when to invert the condition below.  */
    1326          354 :   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
    1327              : 
    1328              :   /* Forward the edges over the middle basic block.  */
    1329          354 :   if (true_edge->dest == middle_bb)
    1330          247 :     true_edge = EDGE_SUCC (true_edge->dest, 0);
    1331          354 :   if (false_edge->dest == middle_bb)
    1332          107 :     false_edge = EDGE_SUCC (false_edge->dest, 0);
    1333              :   /* When THREEWAY_P then e1 will point to the edge of the final transition
    1334              :      from middle-bb to end.  */
    1335          354 :   if (true_edge == e0)
    1336              :     {
    1337          247 :       if (!threeway_p)
    1338          245 :         gcc_assert (false_edge == e1);
    1339              :       arg_true = arg0;
    1340              :       arg_false = arg1;
    1341              :     }
    1342              :   else
    1343              :     {
    1344          107 :       gcc_assert (false_edge == e0);
    1345          107 :       if (!threeway_p)
    1346          107 :         gcc_assert (true_edge == e1);
    1347              :       arg_true = arg1;
    1348              :       arg_false = arg0;
    1349              :     }
    1350          354 :   if (TREE_CODE (arg_true) == SSA_NAME
    1351          354 :       && arg_true != gimple_assign_lhs (other_cmp))
    1352              :     return false;
    1353          354 :   if (TREE_CODE (arg_false) == SSA_NAME
    1354          354 :       && arg_false != gimple_assign_lhs (other_cmp))
    1355              :     return false;
    1356              : 
    1357          354 :   tree larg = gimple_cond_lhs (stmt);
    1358          354 :   tree rarg = gimple_cond_rhs (stmt);
    1359          354 :   if (!operand_equal_p (larg, gimple_assign_rhs1 (other_cmp))
    1360          569 :       || !operand_equal_p (rarg, gimple_assign_rhs2 (other_cmp)))
    1361              :     return false;
    1362              : 
    1363           78 :   tree_code logical;
    1364              :   // a CMP0 b ? 1 : a CMP1 b -> `a CMP0 b || a CMP1 b`
    1365              :   // a CMP0 b ? a CMP1 b : 1 -> `!(a CMP0 b) || a CMP1 b`
    1366              :   
    1367              :   // a CMP0 b ? a CMP1 b : 0 -> `a CMP0 b && a CMP1 b`
    1368              :   // a CMP0 b ? 0 : a CMP1 b -> `!(a CMP0 b) && a CMP1 b`
    1369           78 :   if (integer_onep (arg_true) || integer_onep (arg_false))
    1370              :     logical = TRUTH_ORIF_EXPR;
    1371              :   else
    1372              :     logical = TRUTH_ANDIF_EXPR;
    1373           78 :   tree_code outer_code = gimple_cond_code (stmt);
    1374           78 :   tree_code inner_code = gimple_assign_rhs_code (other_cmp);
    1375              :   // Invert the outter if needed.
    1376           78 :   if (integer_onep (arg_false) || integer_zerop (arg_true))
    1377              :     {
    1378            0 :       outer_code = invert_tree_comparison (outer_code,
    1379              :                                            HONOR_NANS (larg));
    1380              :       // In theory could handle it as !((a CMP0 b) LOGICAL' !(a CMP1 b))
    1381              :       // Most likely the outer comparison will be EQ/NE which is invertable.
    1382            0 :       if (outer_code == ERROR_MARK)
    1383              :         return false;
    1384              :     }
    1385           78 :   tree result;
    1386           78 :   tree_code newcmp_code;
    1387           78 :   newcmp_code = combine_comparisons (logical, outer_code, inner_code,
    1388              :                                      boolean_type_node,
    1389              :                                      HONOR_NANS (larg), &result);
    1390           78 :   if (newcmp_code == ERROR_MARK)
    1391              :     return false;
    1392           16 :   gimple_seq seq = nullptr;
    1393           16 :   if (newcmp_code != INTEGER_CST)
    1394           16 :    result = gimple_build (&seq, newcmp_code, boolean_type_node,
    1395              :                           larg, rarg);
    1396           16 :   gsi = gsi_last_bb (cond_bb);
    1397           16 :   gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
    1398           16 :   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
    1399           16 :   return true;
    1400              : }
    1401              : 
    1402              : /* Update *ARG which is defined in STMT so that it contains the
    1403              :    computed value if that seems profitable.  Return true if the
    1404              :    statement is made dead by that rewriting.  */
    1405              : 
    1406              : static bool
    1407       339770 : jump_function_from_stmt (tree *arg, gimple *stmt)
    1408              : {
    1409       339770 :   enum tree_code code = gimple_assign_rhs_code (stmt);
    1410       339770 :   if (code == ADDR_EXPR)
    1411              :     {
    1412              :       /* For arg = &p->i transform it to p, if possible.  */
    1413         5110 :       tree rhs1 = gimple_assign_rhs1 (stmt);
    1414         5110 :       poly_int64 offset;
    1415         5110 :       tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs1, 0),
    1416              :                                                 &offset);
    1417         5110 :       if (tem
    1418         5029 :           && TREE_CODE (tem) == MEM_REF
    1419        10139 :           && known_eq (mem_ref_offset (tem) + offset, 0))
    1420              :         {
    1421         2358 :           *arg = TREE_OPERAND (tem, 0);
    1422         2358 :           return true;
    1423              :         }
    1424              :     }
    1425              :   /* TODO: Much like IPA-CP jump-functions we want to handle constant
    1426              :      additions symbolically here, and we'd need to update the comparison
    1427              :      code that compares the arg + cst tuples in our caller.  For now the
    1428              :      code above exactly handles the VEC_BASE pattern from vec.h.  */
    1429              :   return false;
    1430              : }
    1431              : 
    1432              : /* RHS is a source argument in a BIT_AND_EXPR or BIT_IOR_EXPR which feeds
    1433              :    a conditional of the form SSA_NAME NE 0.
    1434              : 
    1435              :    If RHS is fed by a simple EQ_EXPR or NE_EXPR comparison of two values,
    1436              :    see if the two input values of the comparison match arg0 and arg1.
    1437              : 
    1438              :    If so update *code and return TRUE.  Otherwise return FALSE.  */
    1439              : 
    1440              : static bool
    1441       162716 : rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1,
    1442              :                                   enum tree_code *code, const_tree rhs,
    1443              :                                   enum tree_code bit_expression_code)
    1444              : {
    1445              :   /* Obviously if RHS is not an SSA_NAME, we can't look at the defining
    1446              :      statement.  */
    1447       162716 :   if (TREE_CODE (rhs) == SSA_NAME)
    1448              :     {
    1449       127285 :       gimple *def1 = SSA_NAME_DEF_STMT (rhs);
    1450              : 
    1451              :       /* Verify the defining statement has an EQ_EXPR or NE_EXPR on the RHS.  */
    1452       127285 :       if (is_gimple_assign (def1)
    1453       127285 :           && ((bit_expression_code == BIT_AND_EXPR
    1454        78394 :                && gimple_assign_rhs_code (def1) == EQ_EXPR)
    1455        95159 :               || (bit_expression_code == BIT_IOR_EXPR
    1456        38813 :                   && gimple_assign_rhs_code (def1) == NE_EXPR)))
    1457              :         {
    1458              :           /* Finally verify the source operands of the EQ_EXPR or NE_EXPR
    1459              :              are equal to arg0 and arg1.  */
    1460        27180 :           tree op0 = gimple_assign_rhs1 (def1);
    1461        27180 :           tree op1 = gimple_assign_rhs2 (def1);
    1462        27180 :           if ((operand_equal_for_phi_arg_p (arg0, op0)
    1463          662 :                && operand_equal_for_phi_arg_p (arg1, op1))
    1464        27781 :               || (operand_equal_for_phi_arg_p (arg0, op1)
    1465          637 :                && operand_equal_for_phi_arg_p (arg1, op0)))
    1466              :             {
    1467              :               /* We will perform the optimization.  */
    1468          473 :               *code = gimple_assign_rhs_code (def1);
    1469          473 :               return true;
    1470              :             }
    1471              :         }
    1472              :     }
    1473              :   return false;
    1474              : }
    1475              : 
    1476              : /* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
    1477              : 
    1478              :    Also return TRUE if arg0/arg1 are equal to the source arguments of an
    1479              :    EQ comparison feeding a BIT_AND_EXPR, or NE comparison feeding a
    1480              :    BIT_IOR_EXPR which feeds COND.
    1481              : 
    1482              :    Return FALSE otherwise.  */
    1483              : 
    1484              : static bool
    1485       681456 : operand_equal_for_value_replacement (const_tree arg0, const_tree arg1,
    1486              :                                      enum tree_code *code, gimple *cond)
    1487              : {
    1488       681456 :   gimple *def;
    1489       681456 :   tree lhs = gimple_cond_lhs (cond);
    1490       681456 :   tree rhs = gimple_cond_rhs (cond);
    1491              : 
    1492       681456 :   if ((operand_equal_for_phi_arg_p (arg0, lhs)
    1493        29235 :        && operand_equal_for_phi_arg_p (arg1, rhs))
    1494       701384 :       || (operand_equal_for_phi_arg_p (arg1, lhs)
    1495        46708 :           && operand_equal_for_phi_arg_p (arg0, rhs)))
    1496              :     return true;
    1497              : 
    1498              :   /* Now handle more complex case where we have an EQ comparison
    1499              :      feeding a BIT_AND_EXPR, or a NE comparison feeding a BIT_IOR_EXPR,
    1500              :      which then feeds into COND.
    1501              : 
    1502              :      First verify that COND is of the form SSA_NAME NE 0.  */
    1503       387830 :   if (*code != NE_EXPR || !integer_zerop (rhs)
    1504       949018 :       || TREE_CODE (lhs) != SSA_NAME)
    1505              :     return false;
    1506              : 
    1507              :   /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR or BIT_OR_EXPR.  */
    1508       280412 :   def = SSA_NAME_DEF_STMT (lhs);
    1509       280412 :   if (!is_gimple_assign (def)
    1510       280412 :       || (gimple_assign_rhs_code (def) != BIT_AND_EXPR
    1511       135827 :           && gimple_assign_rhs_code (def) != BIT_IOR_EXPR))
    1512              :     return false;
    1513              : 
    1514              :   /* Now verify arg0/arg1 correspond to the source arguments of an EQ
    1515              :      comparison feeding the BIT_AND_EXPR or a NE comparison feeding the
    1516              :      BIT_IOR_EXPR.  */
    1517              : 
    1518        81524 :   tree tmp = gimple_assign_rhs1 (def);
    1519        81524 :   if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
    1520              :                                         gimple_assign_rhs_code (def)))
    1521              :     return true;
    1522              : 
    1523        81192 :   tmp = gimple_assign_rhs2 (def);
    1524        81192 :   if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
    1525              :                                         gimple_assign_rhs_code (def)))
    1526              :     return true;
    1527              : 
    1528              :   return false;
    1529              : }
    1530              : 
    1531              : /* Returns true if ARG is a neutral element for operation CODE
    1532              :    on the RIGHT side.  */
    1533              : 
    1534              : static bool
    1535          674 : neutral_element_p (tree_code code, tree arg, bool right)
    1536              : {
    1537          674 :   switch (code)
    1538              :     {
    1539           29 :     case PLUS_EXPR:
    1540           29 :     case BIT_IOR_EXPR:
    1541           29 :     case BIT_XOR_EXPR:
    1542           29 :       return integer_zerop (arg);
    1543              : 
    1544          191 :     case LROTATE_EXPR:
    1545          191 :     case RROTATE_EXPR:
    1546          191 :     case LSHIFT_EXPR:
    1547          191 :     case RSHIFT_EXPR:
    1548          191 :     case MINUS_EXPR:
    1549          191 :     case POINTER_PLUS_EXPR:
    1550          191 :       return right && integer_zerop (arg);
    1551              : 
    1552          327 :     case MULT_EXPR:
    1553          327 :       return integer_onep (arg);
    1554              : 
    1555           31 :     case TRUNC_DIV_EXPR:
    1556           31 :     case CEIL_DIV_EXPR:
    1557           31 :     case FLOOR_DIV_EXPR:
    1558           31 :     case ROUND_DIV_EXPR:
    1559           31 :     case EXACT_DIV_EXPR:
    1560           31 :       return right && integer_onep (arg);
    1561              : 
    1562            0 :     case BIT_AND_EXPR:
    1563            0 :       return integer_all_onesp (arg);
    1564              : 
    1565              :     default:
    1566              :       return false;
    1567              :     }
    1568              : }
    1569              : 
    1570              : /* Returns true if ARG is an absorbing element for operation CODE.  */
    1571              : 
    1572              : static bool
    1573          881 : absorbing_element_p (tree_code code, tree arg, bool right, tree rval)
    1574              : {
    1575          881 :   switch (code)
    1576              :     {
    1577           18 :     case BIT_IOR_EXPR:
    1578           18 :       return integer_all_onesp (arg);
    1579              : 
    1580           38 :     case MULT_EXPR:
    1581           38 :     case BIT_AND_EXPR:
    1582           38 :       return integer_zerop (arg);
    1583              : 
    1584            3 :     case LSHIFT_EXPR:
    1585            3 :     case RSHIFT_EXPR:
    1586            3 :     case LROTATE_EXPR:
    1587            3 :     case RROTATE_EXPR:
    1588            3 :       return !right && integer_zerop (arg);
    1589              : 
    1590          167 :     case TRUNC_DIV_EXPR:
    1591          167 :     case CEIL_DIV_EXPR:
    1592          167 :     case FLOOR_DIV_EXPR:
    1593          167 :     case ROUND_DIV_EXPR:
    1594          167 :     case EXACT_DIV_EXPR:
    1595          167 :     case TRUNC_MOD_EXPR:
    1596          167 :     case CEIL_MOD_EXPR:
    1597          167 :     case FLOOR_MOD_EXPR:
    1598          167 :     case ROUND_MOD_EXPR:
    1599          167 :       return (!right
    1600            9 :               && integer_zerop (arg)
    1601          175 :               && tree_single_nonzero_p (rval));
    1602              : 
    1603              :     default:
    1604              :       return false;
    1605              :     }
    1606              : }
    1607              : 
    1608              : /*  The function value_replacement does the main work of doing the value
    1609              :     replacement.  Return non-zero if the replacement is done.  Otherwise return
    1610              :     0.  If we remove the middle basic block, return 2.
    1611              :     BB is the basic block where the replacement is going to be done on.  ARG0
    1612              :     is argument 0 from the PHI.  Likewise for ARG1.  */
    1613              : 
    1614              : static int
    1615      2497235 : value_replacement (basic_block cond_bb, basic_block middle_bb,
    1616              :                    edge e0, edge e1, gphi *phi, tree arg0, tree arg1)
    1617              : {
    1618      2497235 :   gimple_stmt_iterator gsi;
    1619      2497235 :   edge true_edge, false_edge;
    1620      2497235 :   enum tree_code code;
    1621      2497235 :   bool empty_or_with_defined_p = true;
    1622              : 
    1623              :   /* Virtual operands don't need to be handled. */
    1624      4444626 :   if (virtual_operand_p (arg1))
    1625              :     return 0;
    1626              : 
    1627              :   /* Special case A ? B : B as this will always simplify to B. */
    1628      1324423 :   if (operand_equal_for_phi_arg_p (arg0, arg1))
    1629              :     return 0;
    1630              : 
    1631      2354914 :   gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb));
    1632      1177457 :   code = gimple_cond_code (cond);
    1633              : 
    1634              :   /* This transformation is only valid for equality comparisons.  */
    1635      1177457 :   if (code != NE_EXPR && code != EQ_EXPR)
    1636              :     return 0;
    1637              : 
    1638              :   /* Do not make conditional undefs unconditional.  */
    1639       710912 :   if ((TREE_CODE (arg0) == SSA_NAME
    1640       549454 :        && ssa_name_maybe_undef_p (arg0))
    1641      1258592 :       || (TREE_CODE (arg1) == SSA_NAME
    1642       308254 :           && ssa_name_maybe_undef_p (arg1)))
    1643              :     return false;
    1644              : 
    1645              :   /* If the type says honor signed zeros we cannot do this
    1646              :      optimization.  */
    1647       694772 :   if (HONOR_SIGNED_ZEROS (arg1))
    1648              :     return 0;
    1649              : 
    1650              :   /* If there is a statement in MIDDLE_BB that defines one of the PHI
    1651              :      arguments, then adjust arg0 or arg1.  */
    1652       681456 :   gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
    1653      2158511 :   while (!gsi_end_p (gsi))
    1654              :     {
    1655      1477055 :       gimple *stmt = gsi_stmt (gsi);
    1656      1477055 :       tree lhs;
    1657      1477055 :       gsi_next_nondebug (&gsi);
    1658      1477055 :       if (!is_gimple_assign (stmt))
    1659              :         {
    1660       208032 :           if (gimple_code (stmt) != GIMPLE_PREDICT
    1661       208032 :               && gimple_code (stmt) != GIMPLE_NOP)
    1662              :             empty_or_with_defined_p = false;
    1663       208032 :           continue;
    1664              :         }
    1665              :       /* Now try to adjust arg0 or arg1 according to the computation
    1666              :          in the statement.  */
    1667      1269023 :       lhs = gimple_assign_lhs (stmt);
    1668       339770 :       if (!(lhs == arg0
    1669       339770 :              && jump_function_from_stmt (&arg0, stmt))
    1670      1271381 :             || (lhs == arg1
    1671            0 :                 && jump_function_from_stmt (&arg1, stmt)))
    1672      1477055 :         empty_or_with_defined_p = false;
    1673              :     }
    1674              : 
    1675              :   /* The middle bb is not empty if there are any phi nodes. */
    1676       681456 :   if (phi_nodes (middle_bb))
    1677        76917 :     empty_or_with_defined_p = false;
    1678              : 
    1679              :   /* We need to know which is the true edge and which is the false
    1680              :       edge so that we know if have abs or negative abs.  */
    1681       681456 :   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
    1682              : 
    1683              :   /* At this point we know we have a COND_EXPR with two successors.
    1684              :      One successor is BB, the other successor is an empty block which
    1685              :      falls through into BB.
    1686              : 
    1687              :      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
    1688              : 
    1689              :      There is a single PHI node at the join point (BB) with two arguments.
    1690              : 
    1691              :      We now need to verify that the two arguments in the PHI node match
    1692              :      the two arguments to the equality comparison.  */
    1693              : 
    1694       681456 :   bool equal_p = operand_equal_for_value_replacement (arg0, arg1, &code, cond);
    1695       681456 :   bool maybe_equal_p = false;
    1696       681456 :   if (!equal_p
    1697       681456 :       && empty_or_with_defined_p
    1698       188610 :       && TREE_CODE (gimple_cond_rhs (cond)) == INTEGER_CST
    1699       829526 :       && (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg0)
    1700       148070 :           ? TREE_CODE (arg1) == INTEGER_CST
    1701       138722 :           : (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg1)
    1702        21502 :              && TREE_CODE (arg0) == INTEGER_CST)))
    1703              :     maybe_equal_p = true;
    1704       661877 :   if (equal_p || maybe_equal_p)
    1705              :     {
    1706        33303 :       edge e;
    1707        33303 :       tree arg;
    1708              : 
    1709              :       /* For NE_EXPR, we want to build an assignment result = arg where
    1710              :          arg is the PHI argument associated with the true edge.  For
    1711              :          EQ_EXPR we want the PHI argument associated with the false edge.  */
    1712        33303 :       e = (code == NE_EXPR ? true_edge : false_edge);
    1713              : 
    1714              :       /* Unfortunately, E may not reach BB (it may instead have gone to
    1715              :          OTHER_BLOCK).  If that is the case, then we want the single outgoing
    1716              :          edge from OTHER_BLOCK which reaches BB and represents the desired
    1717              :          path from COND_BLOCK.  */
    1718        33303 :       if (e->dest == middle_bb)
    1719        15055 :         e = single_succ_edge (e->dest);
    1720              : 
    1721              :       /* Now we know the incoming edge to BB that has the argument for the
    1722              :          RHS of our new assignment statement.  */
    1723        33303 :       if (e0 == e)
    1724              :         arg = arg0;
    1725              :       else
    1726        18248 :         arg = arg1;
    1727              : 
    1728              :       /* If the middle basic block was empty or is defining the
    1729              :          PHI arguments and this is a single phi where the args are different
    1730              :          for the edges e0 and e1 then we can remove the middle basic block. */
    1731        33303 :       if (empty_or_with_defined_p
    1732        33303 :           && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)),
    1733              :                                                  e0, e1) == phi)
    1734              :         {
    1735        19835 :           use_operand_p use_p;
    1736        19835 :           gimple *use_stmt;
    1737              : 
    1738              :           /* Even if arg0/arg1 isn't equal to second operand of cond, we
    1739              :              can optimize away the bb if we can prove it doesn't care whether
    1740              :              phi result is arg0/arg1 or second operand of cond.  Consider:
    1741              :              <bb 2> [local count: 118111600]:
    1742              :              if (i_2(D) == 4)
    1743              :                goto <bb 4>; [97.00%]
    1744              :              else
    1745              :                goto <bb 3>; [3.00%]
    1746              : 
    1747              :              <bb 3> [local count: 3540129]:
    1748              : 
    1749              :              <bb 4> [local count: 118111600]:
    1750              :              # i_6 = PHI <i_2(D)(3), 6(2)>
    1751              :              _3 = i_6 != 0;
    1752              :              Here, carg is 4, oarg is 6, crhs is 0, and because
    1753              :              (4 != 0) == (6 != 0), we don't care if i_6 is 4 or 6, both
    1754              :              have the same outcome.  So, we can optimize this to:
    1755              :              _3 = i_2(D) != 0;
    1756              :              If the single imm use of phi result >, >=, < or <=, similarly
    1757              :              we can check if both carg and oarg compare the same against
    1758              :              crhs using ccode.  */
    1759        19835 :           if (maybe_equal_p
    1760        17982 :               && TREE_CODE (arg) != INTEGER_CST
    1761        37802 :               && single_imm_use (gimple_phi_result (phi), &use_p, &use_stmt))
    1762              :             {
    1763        10201 :               enum tree_code ccode = ERROR_MARK;
    1764        10201 :               tree clhs = NULL_TREE, crhs = NULL_TREE;
    1765        10201 :               tree carg = gimple_cond_rhs (cond);
    1766        10201 :               tree oarg = e0 == e ? arg1 : arg0;
    1767        10201 :               if (is_gimple_assign (use_stmt)
    1768        10201 :                   && (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
    1769              :                       == tcc_comparison))
    1770              :                 {
    1771           57 :                   ccode = gimple_assign_rhs_code (use_stmt);
    1772           57 :                   clhs = gimple_assign_rhs1 (use_stmt);
    1773           57 :                   crhs = gimple_assign_rhs2 (use_stmt);
    1774              :                 }
    1775        10144 :               else if (gimple_code (use_stmt) == GIMPLE_COND)
    1776              :                 {
    1777           79 :                   ccode = gimple_cond_code (use_stmt);
    1778           79 :                   clhs = gimple_cond_lhs (use_stmt);
    1779           79 :                   crhs = gimple_cond_rhs (use_stmt);
    1780              :                 }
    1781          136 :               if (ccode != ERROR_MARK
    1782          136 :                   && clhs == gimple_phi_result (phi)
    1783          233 :                   && TREE_CODE (crhs) == INTEGER_CST)
    1784           45 :                 switch (ccode)
    1785              :                   {
    1786           26 :                   case EQ_EXPR:
    1787           26 :                   case NE_EXPR:
    1788           26 :                     if (!tree_int_cst_equal (crhs, carg)
    1789           26 :                         && !tree_int_cst_equal (crhs, oarg))
    1790              :                       equal_p = true;
    1791              :                     break;
    1792            2 :                   case GT_EXPR:
    1793            4 :                     if (tree_int_cst_lt (crhs, carg)
    1794            2 :                         == tree_int_cst_lt (crhs, oarg))
    1795              :                       equal_p = true;
    1796              :                     break;
    1797            0 :                   case GE_EXPR:
    1798            0 :                     if (tree_int_cst_le (crhs, carg)
    1799            0 :                         == tree_int_cst_le (crhs, oarg))
    1800              :                       equal_p = true;
    1801              :                     break;
    1802           13 :                   case LT_EXPR:
    1803           26 :                     if (tree_int_cst_lt (carg, crhs)
    1804           13 :                         == tree_int_cst_lt (oarg, crhs))
    1805              :                       equal_p = true;
    1806              :                     break;
    1807            4 :                   case LE_EXPR:
    1808            8 :                     if (tree_int_cst_le (carg, crhs)
    1809            4 :                         == tree_int_cst_le (oarg, crhs))
    1810              :                       equal_p = true;
    1811              :                     break;
    1812              :                   default:
    1813              :                     break;
    1814              :                   }
    1815        10185 :               if (equal_p)
    1816              :                 {
    1817           16 :                   tree phires = gimple_phi_result (phi);
    1818           16 :                   if (SSA_NAME_RANGE_INFO (phires))
    1819              :                     {
    1820              :                       /* After the optimization PHI result can have value
    1821              :                          which it couldn't have previously.  */
    1822           15 :                       value_range r (TREE_TYPE (phires));
    1823           15 :                       if (get_global_range_query ()->range_of_expr (r, phires,
    1824              :                                                                     phi))
    1825              :                         {
    1826           15 :                           value_range tmp (carg, carg);
    1827           15 :                           r.union_ (tmp);
    1828           15 :                           reset_flow_sensitive_info (phires);
    1829           15 :                           set_range_info (phires, r);
    1830           15 :                         }
    1831              :                       else
    1832            0 :                         reset_flow_sensitive_info (phires);
    1833           15 :                     }
    1834              :                 }
    1835           16 :               if (equal_p && MAY_HAVE_DEBUG_BIND_STMTS)
    1836              :                 {
    1837           13 :                   imm_use_iterator imm_iter;
    1838           13 :                   tree phires = gimple_phi_result (phi);
    1839           13 :                   tree temp = NULL_TREE;
    1840           13 :                   bool reset_p = false;
    1841              : 
    1842              :                   /* Add # DEBUG D#1 => arg != carg ? arg : oarg.  */
    1843           42 :                   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, phires)
    1844              :                     {
    1845           30 :                       if (!is_gimple_debug (use_stmt))
    1846           13 :                         continue;
    1847           17 :                       if (temp == NULL_TREE)
    1848              :                         {
    1849           12 :                           if (!single_pred_p (middle_bb)
    1850           12 :                               || EDGE_COUNT (gimple_bb (phi)->preds) != 2)
    1851              :                             {
    1852              :                               /* But only if middle_bb has a single
    1853              :                                  predecessor and phi bb has two, otherwise
    1854              :                                  we could use a SSA_NAME not usable in that
    1855              :                                  place or wrong-debug.  */
    1856            1 :                               reset_p = true;
    1857            1 :                               break;
    1858              :                             }
    1859           11 :                           gimple_stmt_iterator gsi
    1860           11 :                             = gsi_after_labels (gimple_bb (phi));
    1861           11 :                           tree type = TREE_TYPE (phires);
    1862           11 :                           temp = build_debug_expr_decl (type);
    1863           11 :                           tree t = build2 (NE_EXPR, boolean_type_node,
    1864              :                                            arg, carg);
    1865           11 :                           t = build3 (COND_EXPR, type, t, arg, oarg);
    1866           11 :                           gimple *g = gimple_build_debug_bind (temp, t, phi);
    1867           11 :                           gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    1868              :                         }
    1869           32 :                       FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
    1870           16 :                         replace_exp (use_p, temp);
    1871           16 :                       update_stmt (use_stmt);
    1872           13 :                     }
    1873           13 :                   if (reset_p)
    1874            1 :                     reset_debug_uses (phi);
    1875              :                 }
    1876              :             }
    1877         9650 :           if (equal_p)
    1878              :             {
    1879         1869 :               replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
    1880              :               /* Note that we optimized this PHI.  */
    1881         1869 :               return 2;
    1882              :             }
    1883              :         }
    1884        13468 :       else if (equal_p)
    1885              :         {
    1886        11871 :           if (!single_pred_p (middle_bb))
    1887              :             return 0;
    1888        11001 :           statistics_counter_event (cfun, "Replace PHI with "
    1889              :                                     "variable/value_replacement", 1);
    1890              : 
    1891              :           /* Replace the PHI arguments with arg. */
    1892        11001 :           SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
    1893        11001 :           SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
    1894        11001 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1895              :             {
    1896            0 :               fprintf (dump_file, "PHI ");
    1897            0 :               print_generic_expr (dump_file, gimple_phi_result (phi));
    1898            0 :               fprintf (dump_file, " reduced for COND_EXPR in block %d to ",
    1899              :                        cond_bb->index);
    1900            0 :               print_generic_expr (dump_file, arg);
    1901            0 :               fprintf (dump_file, ".\n");
    1902              :             }
    1903              :           return 1;
    1904              :         }
    1905              :     }
    1906              : 
    1907       667716 :   if (!single_pred_p (middle_bb))
    1908              :     return 0;
    1909              : 
    1910              :   /* Now optimize (x != 0) ? x + y : y to just x + y.  */
    1911       565472 :   gsi = gsi_last_nondebug_bb (middle_bb);
    1912       565472 :   if (gsi_end_p (gsi))
    1913              :     return 0;
    1914              : 
    1915       394937 :   gimple *assign = gsi_stmt (gsi);
    1916       394937 :   if (!is_gimple_assign (assign)
    1917       394937 :       || (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))
    1918       109288 :           && !POINTER_TYPE_P (TREE_TYPE (arg0))))
    1919              :     return 0;
    1920              : 
    1921       334544 :   if (gimple_assign_rhs_class (assign) != GIMPLE_BINARY_RHS)
    1922              :     {
    1923              :       /* If last stmt of the middle_bb is a conversion, handle it like
    1924              :          a preparation statement through constant evaluation with
    1925              :          checking for UB.  */
    1926       143178 :       enum tree_code sc = gimple_assign_rhs_code (assign);
    1927       143178 :       if (CONVERT_EXPR_CODE_P (sc))
    1928              :         assign = NULL;
    1929              :       else
    1930              :         return 0;
    1931              :     }
    1932              : 
    1933              :   /* Punt if there are (degenerate) PHIs in middle_bb, there should not be.  */
    1934       214360 :   if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
    1935              :     return 0;
    1936              : 
    1937              :   /* Allow up to 2 cheap preparation statements that prepare argument
    1938              :      for assign, e.g.:
    1939              :       if (y_4 != 0)
    1940              :         goto <bb 3>;
    1941              :       else
    1942              :         goto <bb 4>;
    1943              :      <bb 3>:
    1944              :       _1 = (int) y_4;
    1945              :       iftmp.0_6 = x_5(D) r<< _1;
    1946              :      <bb 4>:
    1947              :       # iftmp.0_2 = PHI <iftmp.0_6(3), x_5(D)(2)>
    1948              :      or:
    1949              :       if (y_3(D) == 0)
    1950              :         goto <bb 4>;
    1951              :       else
    1952              :         goto <bb 3>;
    1953              :      <bb 3>:
    1954              :       y_4 = y_3(D) & 31;
    1955              :       _1 = (int) y_4;
    1956              :       _6 = x_5(D) r<< _1;
    1957              :      <bb 4>:
    1958              :       # _2 = PHI <x_5(D)(2), _6(3)>  */
    1959       214360 :   gimple *prep_stmt[2] = { NULL, NULL };
    1960       214360 :   int prep_cnt;
    1961       214360 :   for (prep_cnt = 0; ; prep_cnt++)
    1962              :     {
    1963       275754 :       if (prep_cnt || assign)
    1964       252760 :         gsi_prev_nondebug (&gsi);
    1965       275754 :       if (gsi_end_p (gsi))
    1966              :         break;
    1967              : 
    1968       207431 :       gimple *g = gsi_stmt (gsi);
    1969       207431 :       if (gimple_code (g) == GIMPLE_LABEL)
    1970              :         break;
    1971              : 
    1972       207076 :       if (prep_cnt == 2 || !is_gimple_assign (g))
    1973       145682 :         return 0;
    1974              : 
    1975       182435 :       tree lhs = gimple_assign_lhs (g);
    1976       182435 :       tree rhs1 = gimple_assign_rhs1 (g);
    1977       182435 :       use_operand_p use_p;
    1978       182435 :       gimple *use_stmt;
    1979       182435 :       if (TREE_CODE (lhs) != SSA_NAME
    1980       175533 :           || TREE_CODE (rhs1) != SSA_NAME
    1981       111684 :           || !INTEGRAL_TYPE_P (TREE_TYPE (lhs))
    1982       108111 :           || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
    1983       104312 :           || !single_imm_use (lhs, &use_p, &use_stmt)
    1984       285588 :           || ((prep_cnt || assign)
    1985        81708 :               && use_stmt != (prep_cnt ? prep_stmt[prep_cnt - 1] : assign)))
    1986              :         return 0;
    1987        95660 :       switch (gimple_assign_rhs_code (g))
    1988              :         {
    1989              :         CASE_CONVERT:
    1990              :           break;
    1991        21030 :         case PLUS_EXPR:
    1992        21030 :         case BIT_AND_EXPR:
    1993        21030 :         case BIT_IOR_EXPR:
    1994        21030 :         case BIT_XOR_EXPR:
    1995        21030 :           if (TREE_CODE (gimple_assign_rhs2 (g)) != INTEGER_CST)
    1996              :             return 0;
    1997              :           break;
    1998              :         default:
    1999              :           return 0;
    2000              :         }
    2001        61394 :       prep_stmt[prep_cnt] = g;
    2002        61394 :     }
    2003              : 
    2004              :   /* Only transform if it removes the condition.  */
    2005        68678 :   if (!single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)), e0, e1))
    2006              :     return 0;
    2007              : 
    2008              :   /* Size-wise, this is always profitable.  */
    2009        52168 :   if (optimize_bb_for_speed_p (cond_bb)
    2010              :       /* The special case is useless if it has a low probability.  */
    2011        49318 :       && profile_status_for_fn (cfun) != PROFILE_ABSENT
    2012        60845 :       && EDGE_PRED (middle_bb, 0)->probability < profile_probability::even ()
    2013              :       /* If assign is cheap, there is no point avoiding it.  */
    2014        63714 :       && estimate_num_insns_seq (bb_seq (middle_bb), &eni_time_weights)
    2015        11546 :          >= 3 * estimate_num_insns (cond, &eni_time_weights))
    2016           92 :     return 0;
    2017              : 
    2018        52076 :   tree cond_lhs = gimple_cond_lhs (cond);
    2019        52076 :   tree cond_rhs = gimple_cond_rhs (cond);
    2020              : 
    2021              :   /* Propagate the cond_rhs constant through preparation stmts,
    2022              :      make sure UB isn't invoked while doing that.  */
    2023        53310 :   for (int i = prep_cnt - 1; i >= 0; --i)
    2024              :     {
    2025        13235 :       gimple *g = prep_stmt[i];
    2026        13235 :       tree grhs1 = gimple_assign_rhs1 (g);
    2027        13235 :       if (!operand_equal_for_phi_arg_p (cond_lhs, grhs1))
    2028              :         return 0;
    2029         6821 :       cond_lhs = gimple_assign_lhs (g);
    2030         6821 :       cond_rhs = fold_convert (TREE_TYPE (grhs1), cond_rhs);
    2031         6821 :       if (TREE_CODE (cond_rhs) != INTEGER_CST
    2032         6821 :           || TREE_OVERFLOW (cond_rhs))
    2033              :         return 0;
    2034         1234 :       if (gimple_assign_rhs_class (g) == GIMPLE_BINARY_RHS)
    2035              :         {
    2036          544 :           cond_rhs = int_const_binop (gimple_assign_rhs_code (g), cond_rhs,
    2037          544 :                                       gimple_assign_rhs2 (g));
    2038          544 :           if (TREE_OVERFLOW (cond_rhs))
    2039              :             return 0;
    2040              :         }
    2041         1234 :       cond_rhs = fold_convert (TREE_TYPE (cond_lhs), cond_rhs);
    2042         1234 :       if (TREE_CODE (cond_rhs) != INTEGER_CST
    2043         1234 :           || TREE_OVERFLOW (cond_rhs))
    2044              :         return 0;
    2045              :     }
    2046              : 
    2047        40075 :   tree lhs, rhs1, rhs2;
    2048        40075 :   enum tree_code code_def;
    2049        40075 :   if (assign)
    2050              :     {
    2051        39812 :       lhs = gimple_assign_lhs (assign);
    2052        39812 :       rhs1 = gimple_assign_rhs1 (assign);
    2053        39812 :       rhs2 = gimple_assign_rhs2 (assign);
    2054        39812 :       code_def = gimple_assign_rhs_code (assign);
    2055              :     }
    2056              :   else
    2057              :     {
    2058          263 :       gcc_assert (prep_cnt > 0);
    2059              :       lhs = cond_lhs;
    2060              :       rhs1 = NULL_TREE;
    2061              :       rhs2 = NULL_TREE;
    2062              :       code_def = ERROR_MARK;
    2063              :     }
    2064              : 
    2065        23360 :   if (((code == NE_EXPR && e1 == false_edge)
    2066        19588 :         || (code == EQ_EXPR && e1 == true_edge))
    2067        22853 :       && arg0 == lhs
    2068        62928 :       && ((assign == NULL
    2069          262 :            && operand_equal_for_phi_arg_p (arg1, cond_rhs))
    2070              :           || (assign
    2071        22591 :               && arg1 == rhs1
    2072        14933 :               && operand_equal_for_phi_arg_p (rhs2, cond_lhs)
    2073          385 :               && neutral_element_p (code_def, cond_rhs, true))
    2074        22531 :           || (assign
    2075        22531 :               && arg1 == rhs2
    2076         1013 :               && operand_equal_for_phi_arg_p (rhs1, cond_lhs)
    2077          289 :               && neutral_element_p (code_def, cond_rhs, false))
    2078              :           || (assign
    2079        22531 :               && operand_equal_for_phi_arg_p (arg1, cond_rhs)
    2080         2849 :               && ((operand_equal_for_phi_arg_p (rhs2, cond_lhs)
    2081          247 :                    && absorbing_element_p (code_def, cond_rhs, true, rhs2))
    2082         2848 :                   || (operand_equal_for_phi_arg_p (rhs1, cond_lhs)
    2083          634 :                       && absorbing_element_p (code_def,
    2084              :                                               cond_rhs, false, rhs2))))))
    2085              :     {
    2086           94 :       gsi = gsi_for_stmt (cond);
    2087              :       /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
    2088              :          def-stmt in:
    2089              :            if (n_5 != 0)
    2090              :              goto <bb 3>;
    2091              :            else
    2092              :              goto <bb 4>;
    2093              : 
    2094              :            <bb 3>:
    2095              :            # RANGE [0, 4294967294]
    2096              :            u_6 = n_5 + 4294967295;
    2097              : 
    2098              :            <bb 4>:
    2099              :            # u_3 = PHI <u_6(3), 4294967295(2)>  */
    2100           94 :       reset_flow_sensitive_info (lhs);
    2101           94 :       gimple_stmt_iterator gsi_from;
    2102          263 :       for (int i = prep_cnt - 1; i >= 0; --i)
    2103              :         {
    2104           75 :           tree plhs = gimple_assign_lhs (prep_stmt[i]);
    2105           75 :           reset_flow_sensitive_info (plhs);
    2106           75 :           gsi_from = gsi_for_stmt (prep_stmt[i]);
    2107           75 :           gsi_move_before (&gsi_from, &gsi);
    2108              :         }
    2109           94 :       if (assign)
    2110              :         {
    2111           90 :           gsi_from = gsi_for_stmt (assign);
    2112           90 :           gsi_move_before (&gsi_from, &gsi);
    2113              :         }
    2114           94 :       replace_phi_edge_with_variable (cond_bb, e1, phi, lhs);
    2115           94 :       return 2;
    2116              :     }
    2117              : 
    2118              :   return 0;
    2119              : }
    2120              : 
    2121              : /* Attempt to optimize (x <=> y) cmp 0 and similar comparisons.
    2122              :    For strong ordering <=> try to match something like:
    2123              :     <bb 2> :  // cond3_bb (== cond2_bb)
    2124              :     if (x_4(D) != y_5(D))
    2125              :       goto <bb 3>; [INV]
    2126              :     else
    2127              :       goto <bb 6>; [INV]
    2128              : 
    2129              :     <bb 3> :  // cond_bb
    2130              :     if (x_4(D) < y_5(D))
    2131              :       goto <bb 6>; [INV]
    2132              :     else
    2133              :       goto <bb 4>; [INV]
    2134              : 
    2135              :     <bb 4> :  // middle_bb
    2136              : 
    2137              :     <bb 6> :  // phi_bb
    2138              :     # iftmp.0_2 = PHI <1(4), 0(2), -1(3)>
    2139              :     _1 = iftmp.0_2 == 0;
    2140              : 
    2141              :    and for partial ordering <=> something like:
    2142              : 
    2143              :     <bb 2> :  // cond3_bb
    2144              :     if (a_3(D) == b_5(D))
    2145              :       goto <bb 6>; [50.00%]
    2146              :     else
    2147              :       goto <bb 3>; [50.00%]
    2148              : 
    2149              :     <bb 3> [local count: 536870913]:  // cond2_bb
    2150              :     if (a_3(D) < b_5(D))
    2151              :       goto <bb 6>; [50.00%]
    2152              :     else
    2153              :       goto <bb 4>; [50.00%]
    2154              : 
    2155              :     <bb 4> [local count: 268435456]:  // cond_bb
    2156              :     if (a_3(D) > b_5(D))
    2157              :       goto <bb 6>; [50.00%]
    2158              :     else
    2159              :       goto <bb 5>; [50.00%]
    2160              : 
    2161              :     <bb 5> [local count: 134217728]:  // middle_bb
    2162              : 
    2163              :     <bb 6> [local count: 1073741824]:  // phi_bb
    2164              :     # SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
    2165              :     _2 = SR.27_4 > 0;  */
    2166              : 
    2167              : static bool
    2168       658158 : spaceship_replacement (basic_block cond_bb, basic_block middle_bb,
    2169              :                        edge e0, edge e1, gphi *phi,
    2170              :                        tree arg0, tree arg1)
    2171              : {
    2172       658158 :   tree phires = gimple_phi_result (phi);
    2173      1309018 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (phires))
    2174       523040 :       || TYPE_UNSIGNED (TREE_TYPE (phires))
    2175       262747 :       || !tree_fits_shwi_p (arg0)
    2176        71586 :       || !tree_fits_shwi_p (arg1)
    2177        41453 :       || (!IN_RANGE (tree_to_shwi (arg0), -1, 1)
    2178        18843 :           && tree_to_shwi (arg0) != -128)
    2179       681239 :       || (!IN_RANGE (tree_to_shwi (arg1), -1, 1)
    2180         2750 :           && tree_to_shwi (arg1) != -128))
    2181              :     return false;
    2182              : 
    2183        20389 :   basic_block phi_bb = gimple_bb (phi);
    2184        20389 :   gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest);
    2185        20389 :   if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4))
    2186              :     return false;
    2187              : 
    2188         7687 :   use_operand_p use_p;
    2189         7687 :   gimple *use_stmt;
    2190         7687 :   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phires))
    2191              :     return false;
    2192         7682 :   if (!single_imm_use (phires, &use_p, &use_stmt))
    2193              :     return false;
    2194         7032 :   enum tree_code cmp;
    2195         7032 :   tree lhs, rhs;
    2196         7032 :   gimple *orig_use_stmt = use_stmt;
    2197         7032 :   tree orig_use_lhs = NULL_TREE;
    2198         7032 :   tree temps[2] = { NULL_TREE, NULL_TREE };
    2199              : 
    2200              :   /* Handle std::partial_ordering::_M_reverse(), i.e.
    2201              :      _1 = (unsigned char) phires;
    2202              :      _2 = -_1;
    2203              :      _3 = (signed char) _2;
    2204              :      and uses of _3 in comparison instead of phires.  */
    2205         7032 :   if (gimple_assign_cast_p (use_stmt))
    2206              :     {
    2207          252 :       orig_use_lhs = gimple_assign_lhs (use_stmt);
    2208          252 :       temps[0] = orig_use_lhs;
    2209          252 :       tree ty1 = TREE_TYPE (gimple_assign_rhs1 (use_stmt));
    2210          252 :       tree ty2 = TREE_TYPE (orig_use_lhs);
    2211              : 
    2212          252 :       if (!TYPE_UNSIGNED (ty2) || !INTEGRAL_TYPE_P (ty2))
    2213              :         return false;
    2214          213 :       if (TYPE_PRECISION (ty2) != 8 || TYPE_PRECISION (ty1) < 8)
    2215              :         return false;
    2216           94 :       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
    2217              :         return false;
    2218           94 :       if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
    2219              :         return false;
    2220              : 
    2221           93 :       if (!is_gimple_assign (use_stmt)
    2222           93 :           || gimple_assign_rhs_code (use_stmt) != NEGATE_EXPR)
    2223              :         return false;
    2224              : 
    2225           78 :       orig_use_lhs = gimple_assign_lhs (use_stmt);
    2226           78 :       temps[1] = orig_use_lhs;
    2227           78 :       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
    2228              :         return false;
    2229           78 :       if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
    2230              :         return false;
    2231              : 
    2232           78 :       if (!gimple_assign_cast_p (use_stmt))
    2233              :         return false;
    2234              : 
    2235           78 :       orig_use_lhs = gimple_assign_lhs (use_stmt);
    2236           78 :       tree ty3 = TREE_TYPE (orig_use_lhs);
    2237              : 
    2238           78 :       if (!useless_type_conversion_p (ty3, ty1))
    2239              :         return false;
    2240           78 :       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
    2241              :         return false;
    2242           78 :       if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
    2243              :         return false;
    2244              :     }
    2245         6858 :   if (gimple_code (use_stmt) == GIMPLE_COND)
    2246              :     {
    2247         2478 :       cmp = gimple_cond_code (use_stmt);
    2248         2478 :       lhs = gimple_cond_lhs (use_stmt);
    2249         2478 :       rhs = gimple_cond_rhs (use_stmt);
    2250              :     }
    2251         4380 :   else if (is_gimple_assign (use_stmt))
    2252              :     {
    2253         2512 :       if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
    2254              :         {
    2255         1338 :           cmp = gimple_assign_rhs_code (use_stmt);
    2256         1338 :           lhs = gimple_assign_rhs1 (use_stmt);
    2257         1338 :           rhs = gimple_assign_rhs2 (use_stmt);
    2258              :         }
    2259         1174 :       else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
    2260              :         {
    2261            0 :           tree cond = gimple_assign_rhs1 (use_stmt);
    2262            0 :           if (!COMPARISON_CLASS_P (cond))
    2263              :             return false;
    2264            0 :           cmp = TREE_CODE (cond);
    2265            0 :           lhs = TREE_OPERAND (cond, 0);
    2266            0 :           rhs = TREE_OPERAND (cond, 1);
    2267              :         }
    2268              :       else
    2269              :         return false;
    2270              :     }
    2271              :   else
    2272              :     return false;
    2273         3816 :   switch (cmp)
    2274              :     {
    2275         3328 :     case EQ_EXPR:
    2276         3328 :     case NE_EXPR:
    2277         3328 :     case LT_EXPR:
    2278         3328 :     case GT_EXPR:
    2279         3328 :     case LE_EXPR:
    2280         3328 :     case GE_EXPR:
    2281         3328 :       break;
    2282              :     default:
    2283              :       return false;
    2284              :     }
    2285         6578 :   if (lhs != (orig_use_lhs ? orig_use_lhs : phires)
    2286         2965 :       || !tree_fits_shwi_p (rhs)
    2287         2703 :       || !IN_RANGE (tree_to_shwi (rhs), -1, 1))
    2288              :     return false;
    2289              : 
    2290         2691 :   if (!empty_block_p (middle_bb))
    2291              :     return false;
    2292              : 
    2293         5382 :   gcond *cond1 = as_a <gcond *> (*gsi_last_bb (cond_bb));
    2294         2691 :   enum tree_code cmp1 = gimple_cond_code (cond1);
    2295         2691 :   switch (cmp1)
    2296              :     {
    2297         2555 :     case LT_EXPR:
    2298         2555 :     case LE_EXPR:
    2299         2555 :     case GT_EXPR:
    2300         2555 :     case GE_EXPR:
    2301         2555 :       break;
    2302              :     default:
    2303              :       return false;
    2304              :     }
    2305         2555 :   tree lhs1 = gimple_cond_lhs (cond1);
    2306         2555 :   tree rhs1 = gimple_cond_rhs (cond1);
    2307         2555 :   if (TREE_CODE (lhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs1))
    2308              :     return false;
    2309         2555 :   if (TREE_CODE (rhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
    2310              :     return false;
    2311              : 
    2312         2555 :   if (!single_pred_p (cond_bb) || !cond_only_block_p (cond_bb))
    2313              :     return false;
    2314              : 
    2315         2531 :   basic_block cond2_bb = single_pred (cond_bb);
    2316         2531 :   if (EDGE_COUNT (cond2_bb->succs) != 2)
    2317              :     return false;
    2318         2531 :   edge cond2_phi_edge;
    2319         2531 :   if (EDGE_SUCC (cond2_bb, 0)->dest == cond_bb)
    2320              :     {
    2321         2078 :       if (EDGE_SUCC (cond2_bb, 1)->dest != phi_bb)
    2322              :         return false;
    2323              :       cond2_phi_edge = EDGE_SUCC (cond2_bb, 1);
    2324              :     }
    2325          453 :   else if (EDGE_SUCC (cond2_bb, 0)->dest != phi_bb)
    2326              :     return false;
    2327              :   else
    2328              :     cond2_phi_edge = EDGE_SUCC (cond2_bb, 0);
    2329         2531 :   tree arg2 = gimple_phi_arg_def (phi, cond2_phi_edge->dest_idx);
    2330         2531 :   if (!tree_fits_shwi_p (arg2))
    2331              :     return false;
    2332         5062 :   gcond *cond2 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond2_bb));
    2333         2531 :   if (!cond2)
    2334              :     return false;
    2335         2531 :   enum tree_code cmp2 = gimple_cond_code (cond2);
    2336         2531 :   tree lhs2 = gimple_cond_lhs (cond2);
    2337         2531 :   tree rhs2 = gimple_cond_rhs (cond2);
    2338         2531 :   if (lhs2 == lhs1)
    2339              :     {
    2340         2529 :       if (!operand_equal_p (rhs2, rhs1, 0))
    2341              :         {
    2342          336 :           if ((cmp2 == EQ_EXPR || cmp2 == NE_EXPR)
    2343          336 :               && TREE_CODE (rhs1) == INTEGER_CST
    2344          336 :               && TREE_CODE (rhs2) == INTEGER_CST)
    2345              :             {
    2346              :               /* For integers, we can have cond2 x == 5
    2347              :                  and cond1 x < 5, x <= 4, x <= 5, x < 6,
    2348              :                  x > 5, x >= 6, x >= 5 or x > 4.  */
    2349          336 :               if (tree_int_cst_lt (rhs1, rhs2))
    2350              :                 {
    2351          336 :                   if (wi::ne_p (wi::to_wide (rhs1) + 1, wi::to_wide (rhs2)))
    2352              :                     return false;
    2353          336 :                   if (cmp1 == LE_EXPR)
    2354              :                     cmp1 = LT_EXPR;
    2355            0 :                   else if (cmp1 == GT_EXPR)
    2356              :                     cmp1 = GE_EXPR;
    2357              :                   else
    2358              :                     return false;
    2359              :                 }
    2360              :               else
    2361              :                 {
    2362            0 :                   gcc_checking_assert (tree_int_cst_lt (rhs2, rhs1));
    2363            0 :                   if (wi::ne_p (wi::to_wide (rhs2) + 1, wi::to_wide (rhs1)))
    2364              :                     return false;
    2365            0 :                   if (cmp1 == LT_EXPR)
    2366              :                     cmp1 = LE_EXPR;
    2367            0 :                   else if (cmp1 == GE_EXPR)
    2368              :                     cmp1 = GT_EXPR;
    2369              :                   else
    2370              :                     return false;
    2371              :                 }
    2372              :               rhs1 = rhs2;
    2373              :             }
    2374              :           else
    2375              :             return false;
    2376              :         }
    2377              :     }
    2378            2 :   else if (lhs2 == rhs1)
    2379              :     {
    2380            0 :       if (rhs2 != lhs1)
    2381              :         return false;
    2382              :     }
    2383              :   else
    2384              :     return false;
    2385              : 
    2386         2529 :   tree arg3 = arg2;
    2387         2529 :   basic_block cond3_bb = cond2_bb;
    2388         2529 :   edge cond3_phi_edge = cond2_phi_edge;
    2389         2529 :   gcond *cond3 = cond2;
    2390         2529 :   enum tree_code cmp3 = cmp2;
    2391         2529 :   tree lhs3 = lhs2;
    2392         2529 :   tree rhs3 = rhs2;
    2393         2529 :   if (EDGE_COUNT (phi_bb->preds) == 4)
    2394              :     {
    2395          424 :       if (absu_hwi (tree_to_shwi (arg2)) != 1)
    2396              :         return false;
    2397          416 :       if ((cond2_phi_edge->flags & EDGE_FALSE_VALUE)
    2398          416 :           && HONOR_NANS (TREE_TYPE (lhs1)))
    2399              :         return false;
    2400          320 :       if (e1->flags & EDGE_TRUE_VALUE)
    2401              :         {
    2402          318 :           if (tree_to_shwi (arg0) != -128
    2403          318 :               || absu_hwi (tree_to_shwi (arg1)) != 1
    2404          636 :               || wi::to_widest (arg1) == wi::to_widest (arg2))
    2405              :             return false;
    2406              :         }
    2407            2 :       else if (tree_to_shwi (arg1) != -128
    2408            2 :                || absu_hwi (tree_to_shwi (arg0)) != 1
    2409            4 :                || wi::to_widest (arg0) == wi::to_widest (arg2))
    2410              :         return false;
    2411          320 :       switch (cmp2)
    2412              :         {
    2413          320 :         case LT_EXPR:
    2414          320 :         case LE_EXPR:
    2415          320 :         case GT_EXPR:
    2416          320 :         case GE_EXPR:
    2417          320 :           break;
    2418              :         default:
    2419              :           return false;
    2420              :         }
    2421              :       /* if (x < y) goto phi_bb; else fallthru;
    2422              :          if (x > y) goto phi_bb; else fallthru;
    2423              :          bbx:;
    2424              :          phi_bb:;
    2425              :          is ok, but if x and y are swapped in one of the comparisons,
    2426              :          or the comparisons are the same and operands not swapped,
    2427              :          or the true and false edges are swapped, it is not.
    2428              :          For HONOR_NANS, the edge flags are irrelevant and the comparisons
    2429              :          must be different for non-swapped operands and same for swapped
    2430              :          operands.  */
    2431          320 :       if ((lhs2 == lhs1)
    2432          320 :           ^ ((cmp2 == LT_EXPR || cmp2 == LE_EXPR)
    2433          320 :              != (cmp1 == LT_EXPR || cmp1 == LE_EXPR))
    2434          320 :           ^ ((cond2_phi_edge->flags & EDGE_FALSE_VALUE) != 0))
    2435              :         return false;
    2436          318 :       if (!single_pred_p (cond2_bb) || !cond_only_block_p (cond2_bb))
    2437              :         return false;
    2438          318 :       cond3_bb = single_pred (cond2_bb);
    2439          318 :       if (EDGE_COUNT (cond2_bb->succs) != 2)
    2440              :         return false;
    2441          318 :       if (EDGE_SUCC (cond3_bb, 0)->dest == cond2_bb)
    2442              :         {
    2443          150 :           if (EDGE_SUCC (cond3_bb, 1)->dest != phi_bb)
    2444              :             return false;
    2445              :           cond3_phi_edge = EDGE_SUCC (cond3_bb, 1);
    2446              :         }
    2447          168 :       else if (EDGE_SUCC (cond3_bb, 0)->dest != phi_bb)
    2448              :         return false;
    2449              :       else
    2450              :         cond3_phi_edge = EDGE_SUCC (cond3_bb, 0);
    2451          318 :       arg3 = gimple_phi_arg_def (phi, cond3_phi_edge->dest_idx);
    2452          636 :       cond3 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond3_bb));
    2453          318 :       if (!cond3)
    2454              :         return false;
    2455          318 :       cmp3 = gimple_cond_code (cond3);
    2456          318 :       lhs3 = gimple_cond_lhs (cond3);
    2457          318 :       rhs3 = gimple_cond_rhs (cond3);
    2458          318 :       if (lhs3 == lhs1)
    2459              :         {
    2460          318 :           if (!operand_equal_p (rhs3, rhs1, 0))
    2461              :             return false;
    2462              :         }
    2463            0 :       else if (lhs3 == rhs1)
    2464              :         {
    2465            0 :           if (rhs3 != lhs1)
    2466              :             return false;
    2467              :         }
    2468              :       else
    2469              :         return false;
    2470              :     }
    2471         2105 :   else if (absu_hwi (tree_to_shwi (arg0)) != 1
    2472         2084 :            || absu_hwi (tree_to_shwi (arg1)) != 1
    2473         4189 :            || wi::to_widest (arg0) == wi::to_widest (arg1)
    2474         4189 :            || HONOR_NANS (TREE_TYPE (lhs1)))
    2475              :     return false;
    2476              : 
    2477         2402 :   if (!integer_zerop (arg3) || (cmp3 != EQ_EXPR && cmp3 != NE_EXPR))
    2478              :     return false;
    2479         2402 :   if ((cond3_phi_edge->flags & (cmp3 == EQ_EXPR
    2480         2402 :                                 ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) == 0)
    2481              :     return false;
    2482              : 
    2483              :   /* lhs1 one_cmp rhs1 results in phires of 1.  */
    2484         2402 :   enum tree_code one_cmp;
    2485         4804 :   if ((cmp1 == LT_EXPR || cmp1 == LE_EXPR)
    2486         2546 :       ^ (!integer_onep ((e1->flags & EDGE_TRUE_VALUE) ? arg1 : arg0)))
    2487              :     one_cmp = LT_EXPR;
    2488              :   else
    2489         1778 :     one_cmp = GT_EXPR;
    2490              : 
    2491         2402 :   enum tree_code res_cmp;
    2492         2402 :   bool negate_p = false;
    2493         2402 :   switch (cmp)
    2494              :     {
    2495         1317 :     case EQ_EXPR:
    2496         1317 :       if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
    2497              :         res_cmp = EQ_EXPR;
    2498         1233 :       else if (integer_minus_onep (rhs))
    2499          771 :         res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
    2500          462 :       else if (integer_onep (rhs))
    2501              :         res_cmp = one_cmp;
    2502              :       else
    2503              :         return false;
    2504              :       break;
    2505          998 :     case NE_EXPR:
    2506          998 :       if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
    2507              :         res_cmp = NE_EXPR;
    2508          960 :       else if (integer_minus_onep (rhs))
    2509          484 :         res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
    2510          476 :       else if (integer_onep (rhs))
    2511          686 :         res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
    2512              :       else
    2513              :         return false;
    2514          968 :       if (HONOR_NANS (TREE_TYPE (lhs1)))
    2515              :         negate_p = true;
    2516              :       break;
    2517           27 :     case LT_EXPR:
    2518           27 :       if (integer_onep (rhs))
    2519            0 :         res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
    2520           27 :       else if (integer_zerop (rhs))
    2521           27 :         res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
    2522              :       else
    2523              :         return false;
    2524           27 :       if (HONOR_NANS (TREE_TYPE (lhs1)))
    2525              :         negate_p = true;
    2526              :       break;
    2527            4 :     case LE_EXPR:
    2528            4 :       if (integer_zerop (rhs))
    2529            4 :         res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
    2530            0 :       else if (integer_minus_onep (rhs))
    2531            0 :         res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
    2532              :       else
    2533              :         return false;
    2534            4 :       if (HONOR_NANS (TREE_TYPE (lhs1)))
    2535              :         negate_p = true;
    2536              :       break;
    2537            0 :     case GT_EXPR:
    2538            0 :       if (integer_minus_onep (rhs))
    2539            0 :         res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
    2540            0 :       else if (integer_zerop (rhs))
    2541              :         res_cmp = one_cmp;
    2542              :       else
    2543              :         return false;
    2544              :       break;
    2545           56 :     case GE_EXPR:
    2546           56 :       if (integer_zerop (rhs))
    2547           56 :         res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
    2548            0 :       else if (integer_onep (rhs))
    2549              :         res_cmp = one_cmp;
    2550              :       else
    2551              :         return false;
    2552              :       break;
    2553              :     default:
    2554              :       gcc_unreachable ();
    2555              :     }
    2556         2330 :   if (orig_use_lhs)
    2557           60 :     res_cmp = swap_tree_comparison (res_cmp);
    2558              : 
    2559         2330 :   tree clhs1 = lhs1, crhs1 = rhs1;
    2560         2330 :   if (negate_p)
    2561              :     {
    2562           72 :       if (cfun->can_throw_non_call_exceptions)
    2563            0 :         return false;
    2564           72 :       res_cmp = invert_tree_comparison (res_cmp, false);
    2565           72 :       clhs1 = make_ssa_name (boolean_type_node);
    2566           72 :       gimple *g = gimple_build_assign (clhs1, res_cmp, lhs1, rhs1);
    2567           72 :       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
    2568           72 :       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2569           72 :       crhs1 = boolean_false_node;
    2570           72 :       res_cmp = EQ_EXPR;
    2571              :     }  
    2572              : 
    2573         2330 :   if (gimple_code (use_stmt) == GIMPLE_COND)
    2574              :     {
    2575         1673 :       gcond *use_cond = as_a <gcond *> (use_stmt);
    2576         1673 :       gimple_cond_set_code (use_cond, res_cmp);
    2577         1673 :       gimple_cond_set_lhs (use_cond, clhs1);
    2578         1673 :       gimple_cond_set_rhs (use_cond, crhs1);
    2579              :     }
    2580          657 :   else if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
    2581              :     {
    2582          657 :       gimple_assign_set_rhs_code (use_stmt, res_cmp);
    2583          657 :       gimple_assign_set_rhs1 (use_stmt, clhs1);
    2584          657 :       gimple_assign_set_rhs2 (use_stmt, crhs1);
    2585              :     }
    2586              :   else
    2587              :     {
    2588            0 :       tree cond = build2 (res_cmp, TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
    2589              :                           clhs1, crhs1);
    2590            0 :       gimple_assign_set_rhs1 (use_stmt, cond);
    2591              :     }
    2592         2330 :   update_stmt (use_stmt);
    2593              : 
    2594         2330 :   if (MAY_HAVE_DEBUG_BIND_STMTS)
    2595              :     {
    2596         1947 :       use_operand_p use_p;
    2597         1947 :       imm_use_iterator iter;
    2598         1947 :       bool has_debug_uses = false;
    2599         1947 :       bool has_cast1_debug_uses = false;
    2600         1947 :       bool has_neg_debug_uses = false;
    2601         1947 :       bool has_cast2_debug_uses = false;
    2602         1969 :       FOR_EACH_IMM_USE_FAST (use_p, iter, phires)
    2603              :         {
    2604         1969 :           gimple *use_stmt = USE_STMT (use_p);
    2605         1969 :           if (is_gimple_debug (use_stmt))
    2606              :             {
    2607              :               has_debug_uses = true;
    2608              :               break;
    2609              :             }
    2610         1947 :         }
    2611         1947 :       if (orig_use_lhs)
    2612              :         {
    2613           44 :           FOR_EACH_IMM_USE_FAST (use_p, iter, temps[0])
    2614              :             {
    2615           38 :               gimple *use_stmt = USE_STMT (use_p);
    2616           38 :               if (is_gimple_debug (use_stmt))
    2617              :                 {
    2618              :                   has_debug_uses = true;
    2619              :                   has_cast1_debug_uses = true;
    2620              :                   break;
    2621              :                 }
    2622           22 :             }
    2623           44 :           FOR_EACH_IMM_USE_FAST (use_p, iter, temps[1])
    2624              :             {
    2625           38 :               gimple *use_stmt = USE_STMT (use_p);
    2626           38 :               if (is_gimple_debug (use_stmt))
    2627              :                 {
    2628              :                   has_debug_uses = true;
    2629              :                   has_cast1_debug_uses = true;
    2630              :                   has_neg_debug_uses = true;
    2631              :                   break;
    2632              :                 }
    2633           22 :             }
    2634           22 :           FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs)
    2635              :             {
    2636           16 :               gimple *use_stmt = USE_STMT (use_p);
    2637           16 :               if (is_gimple_debug (use_stmt))
    2638              :                 {
    2639              :                   has_debug_uses = true;
    2640              :                   has_cast1_debug_uses = true;
    2641              :                   has_neg_debug_uses = true;
    2642              :                   has_cast2_debug_uses = true;
    2643              :                   break;
    2644              :                 }
    2645           22 :             }
    2646           22 :           if (has_debug_uses)
    2647              :             {
    2648           22 :               gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
    2649           22 :               tree zero = build_zero_cst (TREE_TYPE (temps[0]));
    2650           22 :               gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
    2651           22 :               update_stmt (orig_use_stmt);
    2652           22 :               gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
    2653           22 :               zero = build_zero_cst (TREE_TYPE (temps[1]));
    2654           22 :               gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
    2655           22 :               update_stmt (SSA_NAME_DEF_STMT (temps[1]));
    2656           22 :               gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
    2657           22 :               zero = build_zero_cst (TREE_TYPE (orig_use_lhs));
    2658           22 :               gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
    2659           22 :               update_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
    2660              :             }
    2661              :         }
    2662              : 
    2663         1947 :       if (has_debug_uses)
    2664              :         {
    2665              :           /* If there are debug uses, emit something like:
    2666              :              # DEBUG D#1 => i_2(D) > j_3(D) ? 1 : -1
    2667              :              # DEBUG D#2 => i_2(D) == j_3(D) ? 0 : D#1
    2668              :              where > stands for the comparison that yielded 1
    2669              :              and replace debug uses of phi result with that D#2.
    2670              :              Ignore the value of -128 if !HONOR_NANS, because if NaNs
    2671              :              aren't expected, all floating point numbers should be
    2672              :              comparable.  If HONOR_NANS, emit something like:
    2673              :              # DEBUG D#1 => i_2(D) < j_3(D) ? -1 : -128
    2674              :              # DEBUG D#2 => i_2(D) > j_3(D) ? 1 : D#1
    2675              :              # DEBUG D#3 => i_2(D) == j_3(D) ? 0 : D#2
    2676              :              instead.  */
    2677         1947 :           gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
    2678         1947 :           tree type = TREE_TYPE (phires);
    2679         1947 :           tree minus_one = build_int_cst (type, -1);
    2680         1947 :           if (HONOR_NANS (TREE_TYPE (lhs1)))
    2681              :             {
    2682          102 :               tree temp3 = build_debug_expr_decl (type);
    2683          204 :               tree t = build2 (one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR,
    2684              :                                boolean_type_node, lhs1, rhs2);
    2685          102 :               t = build3 (COND_EXPR, type, t, minus_one,
    2686              :                           build_int_cst (type, -128));
    2687          102 :               gimple *g = gimple_build_debug_bind (temp3, t, phi);
    2688          102 :               gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2689          102 :               minus_one = temp3;
    2690              :             }
    2691         1947 :           tree temp1 = build_debug_expr_decl (type);
    2692         1947 :           tree t = build2 (one_cmp, boolean_type_node, lhs1, rhs2);
    2693         1947 :           t = build3 (COND_EXPR, type, t, build_one_cst (type),
    2694              :                       minus_one);
    2695         1947 :           gimple *g = gimple_build_debug_bind (temp1, t, phi);
    2696         1947 :           gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2697         1947 :           tree temp2 = build_debug_expr_decl (type);
    2698         1947 :           t = build2 (EQ_EXPR, boolean_type_node, lhs1, rhs2);
    2699         1947 :           t = build3 (COND_EXPR, type, t, build_zero_cst (type), temp1);
    2700         1947 :           g = gimple_build_debug_bind (temp2, t, phi);
    2701         1947 :           gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2702         1947 :           replace_uses_by (phires, temp2);
    2703         1947 :           if (has_cast1_debug_uses)
    2704              :             {
    2705           16 :               tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[0]));
    2706           16 :               t = fold_convert (TREE_TYPE (temps[0]), temp2);
    2707           16 :               g = gimple_build_debug_bind (temp3, t, phi);
    2708           16 :               gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2709           16 :               replace_uses_by (temps[0], temp3);
    2710           16 :               temp2 = temp3;
    2711              :             }
    2712         1947 :           if (has_neg_debug_uses)
    2713              :             {
    2714           16 :               tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[1]));
    2715           16 :               t = fold_build1 (NEGATE_EXPR, TREE_TYPE (temps[1]), temp2);
    2716           16 :               g = gimple_build_debug_bind (temp3, t, phi);
    2717           16 :               gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2718           16 :               replace_uses_by (temps[1], temp3);
    2719           16 :               temp2 = temp3;
    2720              :             }
    2721         1947 :           if (has_cast2_debug_uses)
    2722              :             {
    2723           16 :               tree temp3 = build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
    2724           16 :               t = fold_convert (TREE_TYPE (orig_use_lhs), temp2);
    2725           16 :               g = gimple_build_debug_bind (temp3, t, phi);
    2726           16 :               gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    2727           16 :               replace_uses_by (orig_use_lhs, temp3);
    2728              :             }
    2729              :         }
    2730              :     }
    2731              : 
    2732         2330 :   if (orig_use_lhs)
    2733              :     {
    2734           60 :       gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
    2735           60 :       gsi_remove (&gsi, true);
    2736           60 :       gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
    2737           60 :       gsi_remove (&gsi, true);
    2738           60 :       gsi = gsi_for_stmt (orig_use_stmt);
    2739           60 :       gsi_remove (&gsi, true);
    2740           60 :       release_ssa_name (orig_use_lhs);
    2741           60 :       release_ssa_name (temps[1]);
    2742           60 :       release_ssa_name (temps[0]);
    2743              :     }
    2744              : 
    2745         2330 :   gimple_stmt_iterator psi = gsi_for_stmt (phi);
    2746         2330 :   remove_phi_node (&psi, true);
    2747         2330 :   statistics_counter_event (cfun, "spaceship replacement", 1);
    2748              : 
    2749         2330 :   return true;
    2750              : }
    2751              : 
    2752              : /* Optimize x ? __builtin_fun (x) : C, where C is __builtin_fun (0).
    2753              :    Convert
    2754              : 
    2755              :    <bb 2>
    2756              :    if (b_4(D) != 0)
    2757              :    goto <bb 3>
    2758              :    else
    2759              :    goto <bb 4>
    2760              : 
    2761              :    <bb 3>
    2762              :    _2 = (unsigned long) b_4(D);
    2763              :    _9 = __builtin_popcountl (_2);
    2764              :    OR
    2765              :    _9 = __builtin_popcountl (b_4(D));
    2766              : 
    2767              :    <bb 4>
    2768              :    c_12 = PHI <0(2), _9(3)>
    2769              : 
    2770              :    Into
    2771              :    <bb 2>
    2772              :    _2 = (unsigned long) b_4(D);
    2773              :    _9 = __builtin_popcountl (_2);
    2774              :    OR
    2775              :    _9 = __builtin_popcountl (b_4(D));
    2776              : 
    2777              :    <bb 4>
    2778              :    c_12 = PHI <_9(2)>
    2779              : 
    2780              :    Similarly for __builtin_clz or __builtin_ctz if
    2781              :    C?Z_DEFINED_VALUE_AT_ZERO is 2, optab is present and
    2782              :    instead of 0 above it uses the value from that macro.  */
    2783              : 
    2784              : static bool
    2785       457637 : cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
    2786              :                                       basic_block middle_bb,
    2787              :                                       edge e1, edge e2, gphi *phi,
    2788              :                                       tree arg0, tree arg1)
    2789              : {
    2790       457637 :   gimple_stmt_iterator gsi, gsi_from;
    2791       457637 :   gimple *call;
    2792       457637 :   gimple *cast = NULL;
    2793       457637 :   tree lhs, arg;
    2794              : 
    2795              :   /* Check that
    2796              :    _2 = (unsigned long) b_4(D);
    2797              :    _9 = __builtin_popcountl (_2);
    2798              :    OR
    2799              :    _9 = __builtin_popcountl (b_4(D));
    2800              :    are the only stmts in the middle_bb.  */
    2801              : 
    2802       457637 :   gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
    2803       457637 :   if (gsi_end_p (gsi))
    2804              :     return false;
    2805       292961 :   cast = gsi_stmt (gsi);
    2806       292961 :   gsi_next_nondebug (&gsi);
    2807       292961 :   if (!gsi_end_p (gsi))
    2808              :     {
    2809       141604 :       call = gsi_stmt (gsi);
    2810       141604 :       gsi_next_nondebug (&gsi);
    2811       141604 :       if (!gsi_end_p (gsi))
    2812              :         return false;
    2813              :     }
    2814              :   else
    2815              :     {
    2816              :       call = cast;
    2817              :       cast = NULL;
    2818              :     }
    2819              : 
    2820              :   /* Check that we have a popcount/clz/ctz builtin.  */
    2821       200350 :   if (!is_gimple_call (call))
    2822              :     return false;
    2823              : 
    2824         6032 :   lhs = gimple_get_lhs (call);
    2825              : 
    2826         6032 :   if (lhs == NULL_TREE)
    2827              :     return false;
    2828              : 
    2829         6006 :   combined_fn cfn = gimple_call_combined_fn (call);
    2830         6006 :   if (gimple_call_num_args (call) != 1
    2831         6006 :       && (gimple_call_num_args (call) != 2
    2832              :           || cfn == CFN_CLZ
    2833          578 :           || cfn == CFN_CTZ))
    2834              :     return false;
    2835              : 
    2836         4492 :   arg = gimple_call_arg (call, 0);
    2837              : 
    2838         4492 :   internal_fn ifn = IFN_LAST;
    2839         4492 :   int val = 0;
    2840         4492 :   bool any_val = false;
    2841         4492 :   switch (cfn)
    2842              :     {
    2843              :     CASE_CFN_BSWAP:
    2844              :     CASE_CFN_BITREVERSE:
    2845              :     CASE_CFN_FFS:
    2846              :     CASE_CFN_PARITY:
    2847              :     CASE_CFN_POPCOUNT:
    2848              :       break;
    2849          787 :     CASE_CFN_CLZ:
    2850          787 :       if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
    2851              :         {
    2852          787 :           tree type = TREE_TYPE (arg);
    2853          787 :           if (BITINT_TYPE_P (type))
    2854              :             {
    2855            4 :               if (gimple_call_num_args (call) == 1)
    2856              :                 {
    2857              :                   any_val = true;
    2858              :                   ifn = IFN_CLZ;
    2859              :                   break;
    2860              :                 }
    2861            0 :               if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
    2862              :                 return false;
    2863            0 :               HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
    2864            0 :               if ((int) at_zero != at_zero)
    2865              :                 return false;
    2866            0 :               ifn = IFN_CLZ;
    2867            0 :               val = at_zero;
    2868            0 :               break;
    2869              :             }
    2870          783 :           if (direct_internal_fn_supported_p (IFN_CLZ, type, OPTIMIZE_FOR_BOTH)
    2871         1541 :               && CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
    2872              :                                             val) == 2)
    2873              :             {
    2874              :               ifn = IFN_CLZ;
    2875              :               break;
    2876              :             }
    2877              :         }
    2878              :       return false;
    2879          298 :     CASE_CFN_CTZ:
    2880          298 :       if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
    2881              :         {
    2882          298 :           tree type = TREE_TYPE (arg);
    2883          298 :           if (BITINT_TYPE_P (type))
    2884              :             {
    2885            4 :               if (gimple_call_num_args (call) == 1)
    2886              :                 {
    2887              :                   any_val = true;
    2888              :                   ifn = IFN_CTZ;
    2889              :                   break;
    2890              :                 }
    2891            0 :               if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
    2892              :                 return false;
    2893            0 :               HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
    2894            0 :               if ((int) at_zero != at_zero)
    2895              :                 return false;
    2896            0 :               ifn = IFN_CTZ;
    2897            0 :               val = at_zero;
    2898            0 :               break;
    2899              :             }
    2900          294 :           if (direct_internal_fn_supported_p (IFN_CTZ, type, OPTIMIZE_FOR_BOTH)
    2901          567 :               && CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
    2902              :                                             val) == 2)
    2903              :             {
    2904              :               ifn = IFN_CTZ;
    2905              :               break;
    2906              :             }
    2907              :         }
    2908              :       return false;
    2909            3 :     case CFN_BUILT_IN_CLRSB:
    2910            3 :       val = TYPE_PRECISION (integer_type_node) - 1;
    2911            3 :       break;
    2912            3 :     case CFN_BUILT_IN_CLRSBL:
    2913            3 :       val = TYPE_PRECISION (long_integer_type_node) - 1;
    2914            3 :       break;
    2915            3 :     case CFN_BUILT_IN_CLRSBLL:
    2916            3 :       val = TYPE_PRECISION (long_long_integer_type_node) - 1;
    2917            3 :       break;
    2918              :     default:
    2919              :       return false;
    2920              :     }
    2921              : 
    2922          146 :   if (cast)
    2923              :     {
    2924              :       /* We have a cast stmt feeding popcount/clz/ctz builtin.  */
    2925              :       /* Check that we have a cast prior to that.  */
    2926           55 :       if (gimple_code (cast) != GIMPLE_ASSIGN
    2927           55 :           || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (cast)))
    2928              :         return false;
    2929              :       /* Result of the cast stmt is the argument to the builtin.  */
    2930           25 :       if (arg != gimple_assign_lhs (cast))
    2931              :         return false;
    2932           25 :       arg = gimple_assign_rhs1 (cast);
    2933              :     }
    2934              : 
    2935          232 :   gcond *cond = dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    2936              : 
    2937              :   /* Cond_bb has a check for b_4 [!=|==] 0 before calling the popcount/clz/ctz
    2938              :      builtin.  */
    2939          116 :   if (!cond
    2940          116 :       || (gimple_cond_code (cond) != NE_EXPR
    2941           23 :           && gimple_cond_code (cond) != EQ_EXPR)
    2942          116 :       || !integer_zerop (gimple_cond_rhs (cond))
    2943          113 :       || arg != gimple_cond_lhs (cond))
    2944              :     return false;
    2945              : 
    2946           35 :   edge true_edge, false_edge;
    2947              :   /* We need to know which is the true edge and which is the false
    2948              :      edge so that we know when to invert the condition below.  */
    2949           35 :   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
    2950              : 
    2951              :   /* Forward the edges over the middle basic block.  */
    2952           35 :   if (true_edge->dest == middle_bb)
    2953           35 :     true_edge = EDGE_SUCC (true_edge->dest, 0);
    2954           35 :   if (false_edge->dest == middle_bb)
    2955            0 :     false_edge = EDGE_SUCC (false_edge->dest, 0);
    2956              : 
    2957              :   /* Canonicalize the args with respect to the edges,
    2958              :      arg0 is from the true edge and arg1 is from the
    2959              :      false edge.
    2960              :      That is `cond ? arg0 : arg1`.*/
    2961           35 :   if (true_edge == e1)
    2962           35 :     gcc_assert (false_edge == e2);
    2963              :   else
    2964              :     {
    2965            0 :       gcc_assert (false_edge == e1);
    2966            0 :       gcc_assert (true_edge == e2);
    2967              :       std::swap (arg0, arg1);
    2968              :     }
    2969              : 
    2970              :   /* Canonicalize the args such that we get:
    2971              :      `arg != 0 ? arg0 : arg1`. So swap arg0/arg1
    2972              :      around if cond was an equals.  */
    2973           35 :   if (gimple_cond_code (cond) == EQ_EXPR)
    2974            2 :     std::swap (arg0, arg1);
    2975              : 
    2976              :   /* Check PHI arguments.  */
    2977           35 :   if (lhs != arg0
    2978           33 :       || TREE_CODE (arg1) != INTEGER_CST)
    2979              :     return false;
    2980           25 :   if (any_val)
    2981              :     {
    2982            0 :       if (!tree_fits_shwi_p (arg1))
    2983              :         return false;
    2984            0 :       HOST_WIDE_INT at_zero = tree_to_shwi (arg1);
    2985            0 :       if ((int) at_zero != at_zero)
    2986              :         return false;
    2987            0 :       val = at_zero;
    2988              :     }
    2989           25 :   else if (wi::to_wide (arg1) != val)
    2990              :     return false;
    2991              : 
    2992              :   /* And insert the popcount/clz/ctz builtin and cast stmt before the
    2993              :      cond_bb.  */
    2994           13 :   gsi = gsi_last_bb (cond_bb);
    2995           13 :   if (cast)
    2996              :     {
    2997           13 :       gsi_from = gsi_for_stmt (cast);
    2998           13 :       gsi_move_before (&gsi_from, &gsi);
    2999           13 :       reset_flow_sensitive_info (gimple_get_lhs (cast));
    3000              :     }
    3001           13 :   gsi_from = gsi_for_stmt (call);
    3002           13 :   if (ifn == IFN_LAST
    3003           13 :       || (gimple_call_internal_p (call) && gimple_call_num_args (call) == 2))
    3004            8 :     gsi_move_before (&gsi_from, &gsi);
    3005              :   else
    3006              :     {
    3007              :       /* For __builtin_c[lt]z* force .C[LT]Z ifn, because only
    3008              :          the latter is well defined at zero.  */
    3009            5 :       call = gimple_build_call_internal (ifn, 2, gimple_call_arg (call, 0),
    3010            5 :                                          build_int_cst (integer_type_node, val));
    3011            5 :       gimple_call_set_lhs (call, lhs);
    3012            5 :       gsi_insert_before (&gsi, call, GSI_SAME_STMT);
    3013            5 :       gsi_remove (&gsi_from, true);
    3014              :     }
    3015           13 :   reset_flow_sensitive_info (lhs);
    3016              : 
    3017              :   /* Now update the PHI and remove unneeded bbs.  */
    3018           13 :   replace_phi_edge_with_variable (cond_bb, e2, phi, lhs);
    3019           13 :   return true;
    3020              : }
    3021              : 
    3022              : /* Auxiliary functions to determine the set of memory accesses which
    3023              :    can't trap because they are preceded by accesses to the same memory
    3024              :    portion.  We do that for MEM_REFs, so we only need to track
    3025              :    the SSA_NAME of the pointer indirectly referenced.  The algorithm
    3026              :    simply is a walk over all instructions in dominator order.  When
    3027              :    we see an MEM_REF we determine if we've already seen a same
    3028              :    ref anywhere up to the root of the dominator tree.  If we do the
    3029              :    current access can't trap.  If we don't see any dominating access
    3030              :    the current access might trap, but might also make later accesses
    3031              :    non-trapping, so we remember it.  We need to be careful with loads
    3032              :    or stores, for instance a load might not trap, while a store would,
    3033              :    so if we see a dominating read access this doesn't mean that a later
    3034              :    write access would not trap.  Hence we also need to differentiate the
    3035              :    type of access(es) seen.
    3036              : 
    3037              :    ??? We currently are very conservative and assume that a load might
    3038              :    trap even if a store doesn't (write-only memory).  This probably is
    3039              :    overly conservative.
    3040              : 
    3041              :    We currently support a special case that for !TREE_ADDRESSABLE automatic
    3042              :    variables, it could ignore whether something is a load or store because the
    3043              :    local stack should be always writable.  */
    3044              : 
    3045              : /* A hash-table of references (MEM_REF/ARRAY_REF/COMPONENT_REF), and in which
    3046              :    basic block an *_REF through it was seen, which would constitute a
    3047              :    no-trap region for same accesses.
    3048              : 
    3049              :    Size is needed to support 2 MEM_REFs of different types, like
    3050              :    MEM<double>(s_1) and MEM<long>(s_1), which would compare equal with
    3051              :    OEP_ADDRESS_OF.  */
    3052              : struct ref_to_bb
    3053              : {
    3054              :   tree exp;
    3055              :   HOST_WIDE_INT size;
    3056              :   unsigned int phase;
    3057              :   basic_block bb;
    3058              : };
    3059              : 
    3060              : /* Hashtable helpers.  */
    3061              : 
    3062              : struct refs_hasher : free_ptr_hash<ref_to_bb>
    3063              : {
    3064              :   static inline hashval_t hash (const ref_to_bb *);
    3065              :   static inline bool equal (const ref_to_bb *, const ref_to_bb *);
    3066              : };
    3067              : 
    3068              : /* Used for quick clearing of the hash-table when we see calls.
    3069              :    Hash entries with phase < nt_call_phase are invalid.  */
    3070              : static unsigned int nt_call_phase;
    3071              : 
    3072              : /* The hash function.  */
    3073              : 
    3074              : inline hashval_t
    3075     19965918 : refs_hasher::hash (const ref_to_bb *n)
    3076              : {
    3077     19965918 :   inchash::hash hstate;
    3078     19965918 :   inchash::add_expr (n->exp, hstate, OEP_ADDRESS_OF);
    3079     19965918 :   hstate.add_hwi (n->size);
    3080     19965918 :   return hstate.end ();
    3081              : }
    3082              : 
    3083              : /* The equality function of *P1 and *P2.  */
    3084              : 
    3085              : inline bool
    3086     14557183 : refs_hasher::equal (const ref_to_bb *n1, const ref_to_bb *n2)
    3087              : {
    3088     14557183 :   return operand_equal_p (n1->exp, n2->exp, OEP_ADDRESS_OF)
    3089     14557183 :          && n1->size == n2->size;
    3090              : }
    3091              : 
    3092              : class nontrapping_dom_walker : public dom_walker
    3093              : {
    3094              : public:
    3095      1060283 :   nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
    3096      1060283 :     : dom_walker (direction), m_nontrapping (ps), m_seen_refs (128)
    3097      1060283 :   {}
    3098              : 
    3099              :   edge before_dom_children (basic_block) final override;
    3100              :   void after_dom_children (basic_block) final override;
    3101              : 
    3102              : private:
    3103              : 
    3104              :   /* We see the expression EXP in basic block BB.  If it's an interesting
    3105              :      expression (an MEM_REF through an SSA_NAME) possibly insert the
    3106              :      expression into the set NONTRAP or the hash table of seen expressions.
    3107              :      STORE is true if this expression is on the LHS, otherwise it's on
    3108              :      the RHS.  */
    3109              :   void add_or_mark_expr (basic_block, tree, bool);
    3110              : 
    3111              :   hash_set<tree> *m_nontrapping;
    3112              : 
    3113              :   /* The hash table for remembering what we've seen.  */
    3114              :   hash_table<refs_hasher> m_seen_refs;
    3115              : };
    3116              : 
    3117              : /* Called by walk_dominator_tree, when entering the block BB.  */
    3118              : edge
    3119     11908514 : nontrapping_dom_walker::before_dom_children (basic_block bb)
    3120              : {
    3121     11908514 :   edge e;
    3122     11908514 :   edge_iterator ei;
    3123     11908514 :   gimple_stmt_iterator gsi;
    3124              : 
    3125              :   /* If we haven't seen all our predecessors, clear the hash-table.  */
    3126     26182243 :   FOR_EACH_EDGE (e, ei, bb->preds)
    3127     14968576 :     if ((((size_t)e->src->aux) & 2) == 0)
    3128              :       {
    3129       694847 :         nt_call_phase++;
    3130       694847 :         break;
    3131              :       }
    3132              : 
    3133              :   /* Mark this BB as being on the path to dominator root and as visited.  */
    3134     11908514 :   bb->aux = (void*)(1 | 2);
    3135              : 
    3136              :   /* And walk the statements in order.  */
    3137    108321731 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3138              :     {
    3139     84504703 :       gimple *stmt = gsi_stmt (gsi);
    3140              : 
    3141     84504703 :       if ((gimple_code (stmt) == GIMPLE_ASM && gimple_vdef (stmt))
    3142     84540401 :           || (is_gimple_call (stmt)
    3143      5700046 :               && (!nonfreeing_call_p (stmt) || !nonbarrier_call_p (stmt))))
    3144      5097858 :         nt_call_phase++;
    3145     94806418 :       else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
    3146              :         {
    3147     13447030 :           add_or_mark_expr (bb, gimple_assign_lhs (stmt), true);
    3148     13447030 :           add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false);
    3149              :         }
    3150              :     }
    3151     11908514 :   return NULL;
    3152              : }
    3153              : 
    3154              : /* Called by walk_dominator_tree, when basic block BB is exited.  */
    3155              : void
    3156     11908514 : nontrapping_dom_walker::after_dom_children (basic_block bb)
    3157              : {
    3158              :   /* This BB isn't on the path to dominator root anymore.  */
    3159     11908514 :   bb->aux = (void*)2;
    3160     11908514 : }
    3161              : 
    3162              : /* We see the expression EXP in basic block BB.  If it's an interesting
    3163              :    expression of:
    3164              :      1) MEM_REF
    3165              :      2) ARRAY_REF
    3166              :      3) COMPONENT_REF
    3167              :    possibly insert the expression into the set NONTRAP or the hash table
    3168              :    of seen expressions.  STORE is true if this expression is on the LHS,
    3169              :    otherwise it's on the RHS.  */
    3170              : void
    3171     26894060 : nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store)
    3172              : {
    3173     26894060 :   HOST_WIDE_INT size;
    3174              : 
    3175     26894060 :   if ((TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == ARRAY_REF
    3176     22520153 :        || TREE_CODE (exp) == COMPONENT_REF)
    3177     34143285 :       && (size = int_size_in_bytes (TREE_TYPE (exp))) > 0)
    3178              :     {
    3179     11623127 :       struct ref_to_bb map;
    3180     11623127 :       ref_to_bb **slot;
    3181     11623127 :       struct ref_to_bb *r2bb;
    3182     11623127 :       basic_block found_bb = 0;
    3183              : 
    3184     11623127 :       if (!store)
    3185              :         {
    3186      5349755 :           tree base = get_base_address (exp);
    3187              :           /* Only record a LOAD of a local variable without address-taken, as
    3188              :              the local stack is always writable.  This allows cselim on a STORE
    3189              :              with a dominating LOAD.  */
    3190      5349755 :           if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
    3191      4373296 :             return;
    3192              :         }
    3193              : 
    3194              :       /* Try to find the last seen *_REF, which can trap.  */
    3195      7249831 :       map.exp = exp;
    3196      7249831 :       map.size = size;
    3197      7249831 :       slot = m_seen_refs.find_slot (&map, INSERT);
    3198      7249831 :       r2bb = *slot;
    3199      7249831 :       if (r2bb && r2bb->phase >= nt_call_phase)
    3200       296488 :         found_bb = r2bb->bb;
    3201              : 
    3202              :       /* If we've found a trapping *_REF, _and_ it dominates EXP
    3203              :          (it's in a basic block on the path from us to the dominator root)
    3204              :          then we can't trap.  */
    3205       296488 :       if (found_bb && (((size_t)found_bb->aux) & 1) == 1)
    3206              :         {
    3207        81200 :           m_nontrapping->add (exp);
    3208              :         }
    3209              :       else
    3210              :         {
    3211              :           /* EXP might trap, so insert it into the hash table.  */
    3212      7168631 :           if (r2bb)
    3213              :             {
    3214       994881 :               r2bb->phase = nt_call_phase;
    3215       994881 :               r2bb->bb = bb;
    3216              :             }
    3217              :           else
    3218              :             {
    3219      6173750 :               r2bb = XNEW (struct ref_to_bb);
    3220      6173750 :               r2bb->phase = nt_call_phase;
    3221      6173750 :               r2bb->bb = bb;
    3222      6173750 :               r2bb->exp = exp;
    3223      6173750 :               r2bb->size = size;
    3224      6173750 :               *slot = r2bb;
    3225              :             }
    3226              :         }
    3227              :     }
    3228              : }
    3229              : 
    3230              : /* This is the entry point of gathering non trapping memory accesses.
    3231              :    It will do a dominator walk over the whole function, and it will
    3232              :    make use of the bb->aux pointers.  It returns a set of trees
    3233              :    (the MEM_REFs itself) which can't trap.  */
    3234              : static hash_set<tree> *
    3235      1060283 : get_non_trapping (void)
    3236              : {
    3237      1060283 :   nt_call_phase = 0;
    3238      1060283 :   hash_set<tree> *nontrap = new hash_set<tree>;
    3239              : 
    3240      2120566 :   nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
    3241      1060283 :     .walk (cfun->cfg->x_entry_block_ptr);
    3242              : 
    3243      1060283 :   clear_aux_for_blocks ();
    3244      1060283 :   return nontrap;
    3245              : }
    3246              : 
    3247              : /* Do the main work of conditional store replacement.  We already know
    3248              :    that the recognized pattern looks like so:
    3249              : 
    3250              :    split:
    3251              :      if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
    3252              :    MIDDLE_BB:
    3253              :      something
    3254              :      fallthrough (edge E0)
    3255              :    JOIN_BB:
    3256              :      some more
    3257              : 
    3258              :    ASSIGN is a store in MIDDLE_BB which is the candidate for cselim.  We check
    3259              :    that MIDDLE_BB contains only one store (i.e., ASSIGN), that that store
    3260              :    doesn't trap (not via NOTRAP, but via checking if an access to the same
    3261              :    memory location dominates us, or the store is to a local addressable object)
    3262              :    and that the store has a "simple" RHS.  */
    3263              : 
    3264              : static bool
    3265       441230 : cond_store_replacement (basic_block middle_bb, basic_block join_bb, edge e0,
    3266              :                         edge e1, gimple *assign, hash_set<tree> *nontrap)
    3267              : {
    3268       441230 :   tree lhs, rhs, name, name2;
    3269       441230 :   gphi *newphi;
    3270       441230 :   gassign *new_stmt;
    3271       441230 :   gimple_stmt_iterator gsi;
    3272       441230 :   location_t locus;
    3273              : 
    3274              :   /* Check if middle_bb contains of only one store.  */
    3275       441230 :   if (!assign
    3276       192076 :       || !gimple_assign_single_p (assign)
    3277       474088 :       || gimple_has_volatile_ops (assign))
    3278              :     return false;
    3279              : 
    3280        32657 :   locus = gimple_location (assign);
    3281        32657 :   lhs = gimple_assign_lhs (assign);
    3282        32657 :   rhs = gimple_assign_rhs1 (assign);
    3283        32657 :   if ((!REFERENCE_CLASS_P (lhs)
    3284        32657 :        && !DECL_P (lhs))
    3285        32657 :       || !is_gimple_reg_type (TREE_TYPE (lhs)))
    3286              :     return false;
    3287              : 
    3288              :   /* Make sure all uses (except the rhs) in the single stmt are also available
    3289              :      where we insert to.  */
    3290        32171 :   ssa_op_iter iter;
    3291        32171 :   tree use;
    3292        61987 :   FOR_EACH_SSA_TREE_OPERAND (use, assign, iter, SSA_OP_USE)
    3293              :     {
    3294        34256 :       if (use == rhs)
    3295        13333 :         continue;
    3296              : 
    3297        20923 :       gimple *stmt = SSA_NAME_DEF_STMT (use);
    3298        20923 :       if (stmt && gimple_bb (stmt) == middle_bb)
    3299              :         return false;
    3300              :     }
    3301              : 
    3302              :   /* Prove that we can move the store down.  We could also check
    3303              :      TREE_THIS_NOTRAP here, but in that case we also could move stores,
    3304              :      whose value is not available readily, which we want to avoid.  */
    3305        27731 :   if (nontrap->contains (lhs))
    3306              :     {
    3307              :       /* For local non-addressable variables, a load in the same bb
    3308              :          (though before) will cause the lhs to be in the nontrap hashset.
    3309              :          So need to check if there are no other loads in the middle bb.
    3310              :          FIXME: this is over conserative, this check could be made to
    3311              :          allow loads unrelated to lhs.  */
    3312         5805 :       tree vuse = gimple_vuse (assign);
    3313         5805 :       imm_use_iterator iter;
    3314         5805 :       gimple *use_stmt;
    3315        19590 :       FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
    3316              :         {
    3317        13989 :           if (use_stmt == assign)
    3318         5804 :             continue;
    3319         8185 :           if (gimple_bb (use_stmt) == middle_bb)
    3320          204 :             return false;
    3321         5805 :         }
    3322              :     }
    3323              :   else
    3324              :     {
    3325              :       /* If LHS is an access to a local variable without address-taken
    3326              :          (or when we allow data races) and known not to trap, we could
    3327              :          always safely move down the store.  */
    3328        21926 :       tree base;
    3329        21926 :       if (ref_can_have_store_data_races (lhs)
    3330         1013 :           || tree_could_trap_p (lhs)
    3331              :           /* tree_could_trap_p is a predicate for rvalues, so check
    3332              :              for readonly memory explicitly.  */
    3333        22108 :           || ((base = get_base_address (lhs))
    3334          182 :               && ((DECL_P (base)
    3335          176 :                    && TREE_READONLY (base))
    3336          177 :                   || TREE_CODE (base) == STRING_CST)))
    3337              :         return false;
    3338              :     }
    3339              : 
    3340              :   /* Now we've checked the constraints, so do the transformation:
    3341              :      1) Remove the single store.  */
    3342         5772 :   gsi = gsi_for_stmt (assign);
    3343         5772 :   unlink_stmt_vdef (assign);
    3344         5772 :   gsi_remove (&gsi, true);
    3345         5772 :   release_defs (assign);
    3346              : 
    3347              :   /* Make both store and load use alias-set zero as we have to
    3348              :      deal with the case of the store being a conditional change
    3349              :      of the dynamic type.  */
    3350         5772 :   lhs = unshare_expr (lhs);
    3351         5772 :   tree *basep = &lhs;
    3352        11590 :   while (handled_component_p (*basep))
    3353         5818 :     basep = &TREE_OPERAND (*basep, 0);
    3354         5772 :   if (TREE_CODE (*basep) == MEM_REF
    3355         5772 :       || TREE_CODE (*basep) == TARGET_MEM_REF)
    3356          619 :     TREE_OPERAND (*basep, 1)
    3357         1238 :       = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
    3358              :   else
    3359         5153 :     *basep = build2 (MEM_REF, TREE_TYPE (*basep),
    3360              :                      build_fold_addr_expr (*basep),
    3361              :                      build_zero_cst (ptr_type_node));
    3362              : 
    3363              :   /* 2) Insert a load from the memory of the store to the temporary
    3364              :         on the edge which did not contain the store.  */
    3365         5772 :   gphi *vphi = get_virtual_phi (join_bb);
    3366         5772 :   name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
    3367         5772 :   new_stmt = gimple_build_assign (name, lhs);
    3368         5772 :   gimple_set_location (new_stmt, locus);
    3369              :   /* Set the vuse for the new load.  */
    3370         5772 :   gimple_set_vuse (new_stmt, gimple_phi_arg_def (vphi, e1->dest_idx));
    3371         5772 :   lhs = unshare_expr (lhs);
    3372         5772 :   {
    3373              :     /* Set the no-warning bit on the rhs of the load to avoid uninit
    3374              :        warnings.  */
    3375         5772 :     tree rhs1 = gimple_assign_rhs1 (new_stmt);
    3376         5772 :     suppress_warning (rhs1, OPT_Wuninitialized);
    3377              :   }
    3378         5772 :   gsi_insert_on_edge (e1, new_stmt);
    3379              : 
    3380              :   /* 3) Create a PHI node at the join block, with one argument
    3381              :         holding the old RHS, and the other holding the temporary
    3382              :         where we stored the old memory contents.  */
    3383         5772 :   name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
    3384         5772 :   newphi = create_phi_node (name2, join_bb);
    3385         5772 :   add_phi_arg (newphi, rhs, e0, locus);
    3386         5772 :   add_phi_arg (newphi, name, e1, locus);
    3387              : 
    3388         5772 :   new_stmt = gimple_build_assign (lhs, gimple_phi_result (newphi));
    3389              : 
    3390              :   /* Update the vdef for the new store statement. */
    3391         5772 :   tree newvphilhs = make_ssa_name (gimple_vop (cfun));
    3392         5772 :   tree vdef = gimple_phi_result (vphi);
    3393         5772 :   gimple_set_vuse (new_stmt, newvphilhs);
    3394         5772 :   gimple_set_vdef (new_stmt, vdef);
    3395         5772 :   gimple_phi_set_result (vphi, newvphilhs);
    3396         5772 :   SSA_NAME_DEF_STMT (vdef) = new_stmt;
    3397         5772 :   update_stmt (vphi);
    3398              : 
    3399              :   /* 4) Insert that PHI node.  */
    3400         5772 :   gsi = gsi_after_labels (join_bb);
    3401         5772 :   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
    3402              : 
    3403         5772 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3404              :     {
    3405            1 :       fprintf (dump_file, "\nConditional store replacement happened!");
    3406            1 :       fprintf (dump_file, "\nReplaced the store with a load.");
    3407            1 :       fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
    3408            1 :       print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
    3409              :     }
    3410         5772 :   statistics_counter_event (cfun, "conditional store replacement", 1);
    3411              : 
    3412         5772 :   return true;
    3413              : }
    3414              : 
    3415              : /* Do the main work of conditional store replacement.  */
    3416              : 
    3417              : static bool
    3418       855158 : cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
    3419              :                                   basic_block join_bb, gimple *then_assign,
    3420              :                                   gimple *else_assign,
    3421              :                                   gphi *vphi)
    3422              : {
    3423       855158 :   tree lhs_base, lhs, then_rhs, else_rhs, name;
    3424       855158 :   location_t then_locus, else_locus;
    3425       855158 :   gimple_stmt_iterator gsi;
    3426       855158 :   gphi *newphi = nullptr;
    3427       855158 :   gassign *new_stmt;
    3428              : 
    3429       855158 :   if (then_assign == NULL
    3430       855158 :       || !gimple_assign_single_p (then_assign)
    3431       771737 :       || else_assign == NULL
    3432       771737 :       || !gimple_assign_single_p (else_assign)
    3433       100450 :       || stmt_references_abnormal_ssa_name (then_assign)
    3434       955594 :       || stmt_references_abnormal_ssa_name (else_assign))
    3435              :     return false;
    3436              : 
    3437              :   /* Allow both being clobbers but no other volatile operations. */
    3438       100436 :   if (gimple_clobber_p (then_assign)
    3439       100436 :       && gimple_clobber_p (else_assign))
    3440              :     ;
    3441       182803 :   else if (gimple_has_volatile_ops (then_assign)
    3442       182803 :            || gimple_has_volatile_ops (else_assign))
    3443              :    return false;
    3444              : 
    3445        82916 :   lhs = gimple_assign_lhs (then_assign);
    3446        82916 :   if (!operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0))
    3447              :     return false;
    3448              : 
    3449        32609 :   lhs_base = get_base_address (lhs);
    3450        32609 :   if (lhs_base == NULL_TREE
    3451        32609 :       || (!DECL_P (lhs_base) && TREE_CODE (lhs_base) != MEM_REF))
    3452              :     return false;
    3453              : 
    3454        32531 :   then_rhs = gimple_assign_rhs1 (then_assign);
    3455        32531 :   else_rhs = gimple_assign_rhs1 (else_assign);
    3456        32531 :   then_locus = gimple_location (then_assign);
    3457        32531 :   else_locus = gimple_location (else_assign);
    3458              : 
    3459        32531 :   if (!is_gimple_reg_type (TREE_TYPE (lhs)))
    3460              :     {
    3461              :       /* Handle clobbers separately as operand_equal_p does not check
    3462              :          the kind of the clobbers being the same. */
    3463         6687 :       if (TREE_CLOBBER_P (then_rhs) && TREE_CLOBBER_P (else_rhs))
    3464              :         {
    3465         3083 :           if (CLOBBER_KIND (then_rhs) != CLOBBER_KIND  (else_rhs))
    3466              :             return false;
    3467              :         }
    3468         3604 :       else if (!operand_equal_p (then_rhs, else_rhs))
    3469              :         return false;
    3470              :       /* Currently only handle commoning of `= {}`.   */
    3471         3585 :       if (TREE_CODE (then_rhs) != CONSTRUCTOR)
    3472              :         return false;
    3473              :     }
    3474              : 
    3475        29045 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3476              :     {
    3477            8 :       if (TREE_CLOBBER_P (then_rhs))
    3478            3 :         fprintf(dump_file, "factoring out clobber:\n\tthen:\n");
    3479              :       else
    3480            5 :         fprintf(dump_file, "factoring out stores:\n\tthen:\n");
    3481            8 :       print_gimple_stmt (dump_file, then_assign, 0,
    3482              :                          TDF_VOPS|TDF_MEMSYMS);
    3483            8 :       fprintf(dump_file, "\telse:\n");
    3484            8 :       print_gimple_stmt (dump_file, else_assign, 0,
    3485              :                          TDF_VOPS|TDF_MEMSYMS);
    3486            8 :       fprintf (dump_file, "\n");
    3487              :     }
    3488              : 
    3489              :   /* Now we've checked the constraints, so do the transformation:
    3490              :      1) Remove the stores.  */
    3491        29045 :   gsi = gsi_for_stmt (then_assign);
    3492        29045 :   unlink_stmt_vdef (then_assign);
    3493        29045 :   gsi_remove (&gsi, true);
    3494        29045 :   release_defs (then_assign);
    3495              : 
    3496        29045 :   gsi = gsi_for_stmt (else_assign);
    3497        29045 :   unlink_stmt_vdef (else_assign);
    3498        29045 :   gsi_remove (&gsi, true);
    3499        29045 :   release_defs (else_assign);
    3500              : 
    3501              :   /* 2) Create a PHI node at the join block, with one argument
    3502              :         holding the old RHS, and the other holding the temporary
    3503              :         where we stored the old memory contents.  */
    3504        29045 :   if (operand_equal_p (then_rhs, else_rhs))
    3505              :     name = then_rhs;
    3506              :   else
    3507              :     {
    3508        23630 :       name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
    3509        23630 :       newphi = create_phi_node (name, join_bb);
    3510        23630 :       add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
    3511        23630 :       add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
    3512              :     }
    3513              : 
    3514        29045 :   new_stmt = gimple_build_assign (lhs, name);
    3515              :   /* Update the vdef for the new store statement. */
    3516        29045 :   tree newvphilhs = make_ssa_name (gimple_vop (cfun));
    3517        29045 :   tree vdef = gimple_phi_result (vphi);
    3518        29045 :   gimple_set_vuse (new_stmt, newvphilhs);
    3519        29045 :   gimple_set_vdef (new_stmt, vdef);
    3520        29045 :   gimple_phi_set_result (vphi, newvphilhs);
    3521        29045 :   SSA_NAME_DEF_STMT (vdef) = new_stmt;
    3522        29045 :   update_stmt (vphi);
    3523        29045 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3524              :     {
    3525            8 :       if (newphi)
    3526              :         {
    3527            4 :          fprintf(dump_file, "to use phi:\n");
    3528            4 :           print_gimple_stmt (dump_file, newphi, 0,
    3529              :                              TDF_VOPS|TDF_MEMSYMS);
    3530            4 :           fprintf(dump_file, "\n");
    3531              :         }
    3532              :       else
    3533            4 :         fprintf(dump_file, "to:\n");
    3534            8 :       print_gimple_stmt (dump_file, new_stmt, 0,
    3535              :                          TDF_VOPS|TDF_MEMSYMS);
    3536            8 :       fprintf(dump_file, "\n\n");
    3537              :     }
    3538              : 
    3539              :   /* 3) Insert that new store.  */
    3540        29045 :   gsi = gsi_after_labels (join_bb);
    3541        29045 :   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
    3542              : 
    3543        29045 :   statistics_counter_event (cfun, "if-then-else store replacement", 1);
    3544              : 
    3545        29045 :   return true;
    3546              : }
    3547              : 
    3548              : /* Return the last store in BB with VDEF or NULL if there are
    3549              :    loads following the store. VPHI is where the only use of the
    3550              :    vdef should be.  If ONLYONESTORE is true, then the store is
    3551              :    the only store in the BB.  */
    3552              : 
    3553              : static gimple *
    3554      3410220 : trailing_store_in_bb (basic_block bb, tree vdef, gphi *vphi, bool onlyonestore)
    3555              : {
    3556      3410220 :   if (SSA_NAME_IS_DEFAULT_DEF (vdef))
    3557              :     return NULL;
    3558      3384757 :   gimple *store = SSA_NAME_DEF_STMT (vdef);
    3559      3384757 :   if (gimple_bb (store) != bb
    3560      3384757 :       || gimple_code (store) == GIMPLE_PHI)
    3561              :     return NULL;
    3562              : 
    3563              :   /* Verify there is no other store in this BB if requested.  */
    3564      3336769 :   if (onlyonestore
    3565      1595800 :       && !SSA_NAME_IS_DEFAULT_DEF (gimple_vuse (store))
    3566      1200864 :       && gimple_bb (SSA_NAME_DEF_STMT (gimple_vuse (store))) == bb
    3567      3757962 :       && gimple_code (SSA_NAME_DEF_STMT (gimple_vuse (store))) != GIMPLE_PHI)
    3568              :     return NULL;
    3569              : 
    3570              : 
    3571              :   /* Verify there is no load or store after the store, the vdef of the store
    3572              :      should only be used by the vphi joining the 2 bbs.  */
    3573      2915587 :   use_operand_p use_p;
    3574      2915587 :   gimple *use_stmt;
    3575      5831174 :   if (!single_imm_use (gimple_vdef (store), &use_p, &use_stmt))
    3576              :     return NULL;
    3577      2870263 :   if (use_stmt != vphi)
    3578            0 :     return NULL;
    3579              : 
    3580              :   return store;
    3581              : }
    3582              : 
    3583              : /* Takes a MEM and changes the aliasing set to be zero on it.
    3584              :    This handles all variants include decls. */
    3585              : static tree
    3586          698 : copy_mem_with_alias_set_zero (tree mem)
    3587              : {
    3588          698 :   mem = unshare_expr (mem);
    3589          698 :   tree *basep = &mem;
    3590         1480 :   while (handled_component_p (*basep))
    3591          782 :     basep = &TREE_OPERAND (*basep, 0);
    3592          698 :   if (TREE_CODE (*basep) == MEM_REF
    3593          698 :       || TREE_CODE (*basep) == TARGET_MEM_REF)
    3594          146 :     TREE_OPERAND (*basep, 1)
    3595          292 :       = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
    3596              :   else
    3597          552 :     *basep = build2 (MEM_REF, TREE_TYPE (*basep),
    3598              :                      build_fold_addr_expr (*basep),
    3599              :                      build_zero_cst (ptr_type_node));
    3600          698 :   return mem;
    3601              : }
    3602              : 
    3603              : /* Do the main work of a limited conditional store replacement.
    3604              :    This recognized pattern like so:
    3605              : 
    3606              :    COND_BB:
    3607              :      store = a_1;
    3608              :      // no loads
    3609              :      if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
    3610              :    MIDDLE_BB:
    3611              :      something // no loads
    3612              :      store = a_2;
    3613              :      something // no loads
    3614              :      fallthrough (edge E0)
    3615              :    JOIN_BB:
    3616              :      some more
    3617              : 
    3618              :   This is a limited form of the full cond_store_replacement
    3619              :   to be allowed from use from phiopt and can be done
    3620              :   without calculating the non-trapping cases.  */
    3621              : static bool
    3622      1477793 : cond_store_replacement_limited (basic_block middle_bb, basic_block join_bb,
    3623              :                                 basic_block cond_bb,
    3624              :                                 edge e0, edge e1,
    3625              :                                 bool caninsert_edge)
    3626              : {
    3627      1477793 :   tree lhs, rhs;
    3628      1477793 :   location_t locus;
    3629              :   /* Currently don't handle more than 2 incoming edges
    3630              :      into the merge bb. */
    3631      1477793 :   if (EDGE_COUNT (join_bb->preds) > 2)
    3632              :     return false;
    3633              :   /* The middle bb needs to have a single predecessor of the cond_bb.  */
    3634      1477793 :   if (!single_pred_p (middle_bb))
    3635              :     return false;
    3636      1477793 :   gphi *vphi = get_virtual_phi (join_bb);
    3637      1477793 :   if (!vphi)
    3638              :     return false;
    3639      1306921 :   tree middle_vdef = gimple_phi_arg_def_from_edge (vphi, e0);
    3640              :   /* Check if middle_bb contains of only one store.  */
    3641      1306921 :   gimple *store_middle;
    3642      1306921 :   store_middle = trailing_store_in_bb (middle_bb, middle_vdef,
    3643              :                                        vphi, true);
    3644              : 
    3645      1306921 :   if (!store_middle
    3646       950934 :       || !gimple_assign_single_p (store_middle)
    3647      1454065 :       || gimple_has_volatile_ops (store_middle))
    3648              :     return false;
    3649              : 
    3650       146342 :   locus = gimple_location (store_middle);
    3651       146342 :   lhs = gimple_assign_lhs (store_middle);
    3652       146342 :   rhs = gimple_assign_rhs1 (store_middle);
    3653       146342 :   if ((!REFERENCE_CLASS_P (lhs)
    3654       146342 :        && !DECL_P (lhs))
    3655       146342 :       || !is_gimple_reg_type (TREE_TYPE (lhs)))
    3656              :     return false;
    3657       144056 :   if (TREE_CODE (rhs) != SSA_NAME)
    3658              :     return false;
    3659              : 
    3660              :   /* Three cases that can be handled:
    3661              :      1) the lhs is stored to right before the condition.
    3662              :        Will remove the store before the condition.
    3663              :      2) Or the lhs is loaded from right before the condition.
    3664              :      3) Neither of these. (this will insert a load in the other edge)
    3665              :      For case 2 and 3, check for data races.
    3666              :      For case 2, the load can either be based on a local variable
    3667              :      or a known non-trapping decl.
    3668              :      For case 3, the store needs to known to be non-trapping.  */
    3669        84421 :   tree vuse = gimple_vuse (store_middle);
    3670        84421 :   gimple *beforestore = nullptr;
    3671        84421 :   gimple *vdef_before = SSA_NAME_DEF_STMT (vuse);
    3672        84421 :   tree other_rhs = nullptr;
    3673              : 
    3674              :   /* See if there is a store before the condition case.  */
    3675        84421 :   if (gimple_assign_single_p (vdef_before))
    3676              :     {
    3677        20805 :       tree beforelhs = gimple_assign_lhs (vdef_before);
    3678              :       /* Only allow the store to be right before the condition.  */
    3679        20805 :       if (gimple_bb (vdef_before) == cond_bb
    3680              :           /* This can't be a clobber */
    3681        17848 :           && !gimple_clobber_p (vdef_before)
    3682              :           /* An exact match is only supported.
    3683              :              FIXME: Allow for clique/base mismatch?  */
    3684        35657 :           && operand_equal_p (lhs, beforelhs))
    3685              :         {
    3686              :           /* The vuse of the of store in the middle should be also
    3687              :              the entry in the phi for the other edge.  */
    3688          808 :           gcc_assert (vuse == gimple_phi_arg_def_from_edge (vphi, e1));
    3689          808 :           tree vuse = gimple_vuse (store_middle);
    3690          808 :           imm_use_iterator iter;
    3691          808 :           gimple *use_stmt;
    3692          808 :           bool has_load = false;
    3693              :           /* If there is a load, then just reuse the value and not
    3694              :              remove the old store as that might be used by the load.  */
    3695         1950 :           FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
    3696              :             {
    3697         1609 :               if (use_stmt != store_middle
    3698         1609 :                   && use_stmt != vphi)
    3699              :                 {
    3700              :                   has_load = true;
    3701              :                   break;
    3702              :                 }
    3703          808 :             }
    3704          808 :           other_rhs = gimple_assign_rhs1 (vdef_before);
    3705              :           /* If there is no load, then keep the reference to the store stmt.  */
    3706          808 :           if (!has_load)
    3707          341 :             beforestore = vdef_before;
    3708              :         }
    3709              :     }
    3710              :   /*
    3711              :     case 2:
    3712              :     a = local_var[n];
    3713              :     if (b)
    3714              :       local_var[n] = c;
    3715              : 
    3716              :     case 3:
    3717              :     if (b)
    3718              :       nontrapping = c;
    3719              : 
    3720              :     For case 3, nontrapping needs to satisfy tree_could_trap_p.
    3721              :     In both cases ref_can_have_store_data_races needs to be satisfy.
    3722              :   */
    3723              : 
    3724              :   /* Maybe the load/local non-escaped variable case.  */
    3725          808 :   if (!other_rhs)
    3726              :     {
    3727        83613 :       tree lhsbase = get_base_address (lhs);
    3728              :       /* If this store ref can't have data races, a store
    3729              :          that was conditional can't become unconditional.  */
    3730        83613 :       if (ref_can_have_store_data_races (lhs))
    3731        82915 :         return false;
    3732         5468 :       tree vuse = gimple_vuse (store_middle);
    3733         5468 :       imm_use_iterator iter;
    3734         5468 :       gimple *use_stmt;
    3735              :       /* Try to find the load before the store that matches
    3736              :          if we have a local variable or a non trapping store.  */
    3737        10403 :       if ((auto_var_p (lhsbase) && !TREE_ADDRESSABLE (lhsbase))
    3738         5504 :           || !lhs_could_trap_p (lhs))
    3739              :         {
    3740        25898 :           FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
    3741              :             {
    3742        21146 :               if (gimple_bb (use_stmt) != cond_bb)
    3743        14964 :                 continue;
    3744              :               /* Looking for a load only.  */
    3745         6182 :               if (!gimple_assign_load_p (use_stmt))
    3746            0 :                 continue;
    3747         6182 :               tree rhs = gimple_assign_rhs1 (use_stmt);
    3748         6182 :               if (!operand_equal_p (rhs, lhs))
    3749         5973 :                 continue;
    3750          209 :               other_rhs = gimple_assign_lhs (use_stmt);
    3751          209 :               lhs = copy_mem_with_alias_set_zero (lhs);
    3752          209 :               break;
    3753         4961 :             }
    3754              :         }
    3755         5468 :       if (!other_rhs)
    3756              :         {
    3757         5259 :           gassign *new_stmt;
    3758              :           /* If not allowing inserting on the edge, then don't.  */
    3759         5259 :           if (!caninsert_edge)
    3760              :             return false;
    3761              :           /* If LHS is an access to a local variable without address-taken
    3762              :              (or when we allow data races) and known not to trap, we could
    3763              :              always safely move down the store.  */
    3764         1587 :           if (lhs_could_trap_p (lhs))
    3765              :             return false;
    3766          489 :           lhs = copy_mem_with_alias_set_zero (lhs);
    3767              :           /* Insert a load from the memory of the store to the temporary
    3768              :              on the edge which did not contain the store.  */
    3769          489 :           other_rhs = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
    3770          489 :           new_stmt = gimple_build_assign (other_rhs, lhs);
    3771          489 :           gimple_set_location (new_stmt, locus);
    3772              :           /* Set the vuse for the new load.  */
    3773          489 :           gimple_set_vuse (new_stmt,
    3774          489 :                            gimple_phi_arg_def (vphi, e1->dest_idx));
    3775          489 :           lhs = unshare_expr (lhs);
    3776          489 :           {
    3777              :             /* Set the no-warning bit on the rhs of the load to avoid
    3778              :                uninit warnings.  */
    3779          489 :             tree rhs1 = gimple_assign_rhs1 (new_stmt);
    3780          489 :             suppress_warning (rhs1, OPT_Wuninitialized);
    3781              :           }
    3782          489 :           gsi_insert_on_edge (e1, new_stmt);
    3783              :         }
    3784              :     }
    3785              : 
    3786         1506 :   gphi *newphi;
    3787         1506 :   gassign *new_stmt;
    3788         1506 :   gimple_stmt_iterator gsi;
    3789              :   /* Now we've checked the constraints, so do the transformation:
    3790              :      1) Remove the store(s).  */
    3791         1506 :   gsi = gsi_for_stmt (store_middle);
    3792         1506 :   unlink_stmt_vdef (store_middle);
    3793         1506 :   gsi_remove (&gsi, true);
    3794         1506 :   release_defs (store_middle);
    3795              : 
    3796              :   /* Remove the store before the conditional if possible.  */
    3797         1506 :   if (beforestore)
    3798              :     {
    3799          341 :       gsi = gsi_for_stmt (beforestore);
    3800          341 :       unlink_stmt_vdef (beforestore);
    3801          341 :       gsi_remove (&gsi, true);
    3802          341 :       release_defs (beforestore);
    3803              :     }
    3804              : 
    3805              : 
    3806              :   /* 2) Create a PHI node at the join block, with one argument
    3807              :         holding the old RHS, and the other holding the temporary
    3808              :         where we stored the old memory contents.  */
    3809         1506 :   tree phiname = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
    3810         1506 :   newphi = create_phi_node (phiname, join_bb);
    3811         1506 :   add_phi_arg (newphi, rhs, e0, locus);
    3812         1506 :   add_phi_arg (newphi, other_rhs, e1, locus);
    3813              : 
    3814              :   /* 3. Create the new store.  */
    3815         1506 :   new_stmt = gimple_build_assign (lhs, phiname);
    3816              : 
    3817              :   /* Update the vdef for the new store statement. */
    3818         1506 :   tree newvphilhs = make_ssa_name (gimple_vop (cfun));
    3819         1506 :   tree vdef = gimple_phi_result (vphi);
    3820         1506 :   gimple_set_vuse (new_stmt, newvphilhs);
    3821         1506 :   gimple_set_vdef (new_stmt, vdef);
    3822         1506 :   gimple_phi_set_result (vphi, newvphilhs);
    3823         1506 :   SSA_NAME_DEF_STMT (vdef) = new_stmt;
    3824         1506 :   update_stmt (vphi);
    3825              : 
    3826         1506 :   gsi = gsi_after_labels (join_bb);
    3827         1506 :   gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
    3828              : 
    3829         1506 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3830              :     {
    3831           12 :       fprintf (dump_file, "\nConditional store replacement happened!");
    3832           12 :       if (beforestore)
    3833            4 :         fprintf (dump_file, "\nRemoved the store before the condition.");
    3834           12 :       fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
    3835           12 :       print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
    3836              :     }
    3837         1506 :   statistics_counter_event (cfun, "conditional store replacement", 1);
    3838         1506 :   return true;
    3839              : }
    3840              : 
    3841              : 
    3842              : /* Return the only store in MIDDLE_BB as the candidate store for cselim.  Return
    3843              :    NULL if no candidate can be found.  */
    3844              : 
    3845              : static gimple *
    3846       441230 : cselim_candidate (basic_block middle_bb, basic_block join_bb, edge e0)
    3847              : {
    3848       441230 :   gphi *vphi = get_virtual_phi (join_bb);
    3849       441230 :   if (!vphi)
    3850              :     return NULL;
    3851              : 
    3852       270358 :   tree middle_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, e0);
    3853       270358 :   return trailing_store_in_bb (middle_bb, middle_vdef, vphi, true);
    3854              : }
    3855              : 
    3856              : /* Limited Conditional store replacement.  We already know
    3857              :    that the recognized pattern looks like so:
    3858              : 
    3859              :    split:
    3860              :      if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
    3861              :    THEN_BB:
    3862              :      ...
    3863              :      STORE = Y;
    3864              :      ...
    3865              :      goto JOIN_BB;
    3866              :    ELSE_BB:
    3867              :      ...
    3868              :      STORE = Z;
    3869              :      ...
    3870              :      fallthrough (edge E0)
    3871              :    JOIN_BB:
    3872              :      some more
    3873              : 
    3874              :    Handles only the case with store in THEN_BB and ELSE_BB.  That is
    3875              :    cheap enough due to in phiopt and not worry about heurstics.  Moving the store
    3876              :    out might provide an opportunity for a phiopt to happen.
    3877              :    At -O1 (!flag_expensive_optimizations), this only handles the only store in
    3878              :    the BBs.  */
    3879              : 
    3880              : static bool
    3881       959223 : cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb,
    3882              :                                         basic_block join_bb)
    3883              : {
    3884       959223 :   gphi *vphi = get_virtual_phi (join_bb);
    3885       959223 :   if (!vphi)
    3886              :     return false;
    3887              : 
    3888       959223 :   tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb));
    3889      1918446 :   gimple *then_assign = trailing_store_in_bb (then_bb, then_vdef, vphi,
    3890       959223 :                                               !flag_expensive_optimizations);
    3891       959223 :   if (!then_assign)
    3892              :     return false;
    3893              : 
    3894       873718 :   tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb));
    3895      1747436 :   gimple *else_assign = trailing_store_in_bb (else_bb, else_vdef, vphi,
    3896       873718 :                                               !flag_expensive_optimizations);
    3897       873718 :   if (!else_assign)
    3898              :     return false;
    3899              : 
    3900       853535 :   return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
    3901       853535 :                                            then_assign, else_assign, vphi);
    3902              : }
    3903              : 
    3904              : /* Conditional store replacement.  We already know
    3905              :    that the recognized pattern looks like so:
    3906              : 
    3907              :    split:
    3908              :      if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
    3909              :    THEN_BB:
    3910              :      ...
    3911              :      X = Y;
    3912              :      ...
    3913              :      goto JOIN_BB;
    3914              :    ELSE_BB:
    3915              :      ...
    3916              :      X = Z;
    3917              :      ...
    3918              :      fallthrough (edge E0)
    3919              :    JOIN_BB:
    3920              :      some more
    3921              : 
    3922              :    We check that it is safe to sink the store to JOIN_BB by verifying that
    3923              :    there are no read-after-write or write-after-write dependencies in
    3924              :    THEN_BB and ELSE_BB.  */
    3925              : 
    3926              : static bool
    3927       240899 : cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
    3928              :                                 basic_block join_bb)
    3929              : {
    3930       240899 :   vec<data_reference_p> then_datarefs, else_datarefs;
    3931       240899 :   vec<ddr_p> then_ddrs, else_ddrs;
    3932       240899 :   gimple *then_store, *else_store;
    3933       240899 :   bool found, ok = false, res;
    3934       240899 :   tree then_lhs, else_lhs;
    3935       240899 :   basic_block blocks[3];
    3936       240899 :   gphi *vphi = get_virtual_phi (join_bb);
    3937       240899 :   if (!vphi)
    3938              :     return false;
    3939              : 
    3940              :   /* Handle the case with trailing stores in THEN_BB and ELSE_BB.  That is
    3941              :      cheap enough to always handle as it allows us to elide dependence
    3942              :      checking.  */
    3943       239060 :   while (cond_if_else_store_replacement_limited (then_bb, else_bb, join_bb))
    3944              :     ;
    3945              : 
    3946              :   /* If either vectorization or if-conversion is disabled then do
    3947              :      not sink any stores.  */
    3948       224859 :   if (param_max_stores_to_sink == 0
    3949       224858 :       || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize)
    3950       219195 :       || !flag_tree_loop_if_convert)
    3951              :     return false;
    3952              : 
    3953              :   /* Find data references.  */
    3954       219192 :   then_datarefs.create (1);
    3955       219192 :   else_datarefs.create (1);
    3956       219192 :   if ((find_data_references_in_bb (NULL, then_bb, &then_datarefs)
    3957       219192 :         == chrec_dont_know)
    3958       193626 :       || !then_datarefs.length ()
    3959       187712 :       || (find_data_references_in_bb (NULL, else_bb, &else_datarefs)
    3960       187712 :           == chrec_dont_know)
    3961       234756 :       || !else_datarefs.length ())
    3962              :     {
    3963       204679 :       free_data_refs (then_datarefs);
    3964       204679 :       free_data_refs (else_datarefs);
    3965       204679 :       return false;
    3966              :     }
    3967              : 
    3968              :   /* Clear visited on else stores, we want to make sure to pick each store
    3969              :      at most once to avoid quadratic behavior.  */
    3970        66639 :   for (auto else_dr : else_datarefs)
    3971              :     {
    3972        37613 :       if (DR_IS_READ (else_dr))
    3973        19471 :         continue;
    3974        18142 :       gimple_set_visited (DR_STMT (else_dr), false);
    3975              :     }
    3976              : 
    3977              :   /* Find pairs of stores with equal LHS.  Work from the end to avoid
    3978              :      re-ordering stores unnecessarily.  */
    3979        14513 :   auto_vec<std::pair<gimple *, gimple *>, 1> stores_pairs;
    3980        14513 :   unsigned i;
    3981        14513 :   data_reference_p then_dr;
    3982        61493 :   FOR_EACH_VEC_ELT_REVERSE (then_datarefs, i, then_dr)
    3983              :     {
    3984        32467 :       if (DR_IS_READ (then_dr))
    3985        32467 :         continue;
    3986              : 
    3987        19481 :       then_store = DR_STMT (then_dr);
    3988        19481 :       then_lhs = gimple_get_lhs (then_store);
    3989        19481 :       if (then_lhs == NULL_TREE)
    3990            0 :         continue;
    3991        19481 :       found = false;
    3992              : 
    3993        19481 :       unsigned j;
    3994        19481 :       data_reference_p else_dr;
    3995        92081 :       FOR_EACH_VEC_ELT_REVERSE (else_datarefs, j, else_dr)
    3996              :         {
    3997        56813 :           if (DR_IS_READ (else_dr))
    3998        20530 :             continue;
    3999              : 
    4000        36283 :           else_store = DR_STMT (else_dr);
    4001        36283 :           if (gimple_visited_p (else_store))
    4002         3316 :             continue;
    4003        32967 :           else_lhs = gimple_get_lhs (else_store);
    4004        32967 :           if (else_lhs == NULL_TREE)
    4005            0 :             continue;
    4006              : 
    4007        32967 :           if (operand_equal_p (then_lhs, else_lhs, 0))
    4008              :             {
    4009              :               found = true;
    4010              :               break;
    4011              :             }
    4012              :         }
    4013              : 
    4014        19481 :       if (!found)
    4015        15787 :         continue;
    4016              : 
    4017         3694 :       gimple_set_visited (else_store, true);
    4018         3694 :       stores_pairs.safe_push (std::make_pair (then_store, else_store));
    4019              :     }
    4020              : 
    4021              :   /* No pairs of stores found.  */
    4022        14513 :   if (!stores_pairs.length ()
    4023        14513 :       || stores_pairs.length () > (unsigned) param_max_stores_to_sink)
    4024              :     {
    4025        12371 :       free_data_refs (then_datarefs);
    4026        12371 :       free_data_refs (else_datarefs);
    4027        12371 :       return false;
    4028              :     }
    4029              : 
    4030              :   /* Compute and check data dependencies in both basic blocks.  */
    4031         2142 :   then_ddrs.create (1);
    4032         2142 :   else_ddrs.create (1);
    4033         2142 :   if (!compute_all_dependences (then_datarefs, &then_ddrs,
    4034         2142 :                                 vNULL, false)
    4035         4284 :       || !compute_all_dependences (else_datarefs, &else_ddrs,
    4036         2142 :                                    vNULL, false))
    4037              :     {
    4038            0 :       free_dependence_relations (then_ddrs);
    4039            0 :       free_dependence_relations (else_ddrs);
    4040            0 :       free_data_refs (then_datarefs);
    4041            0 :       free_data_refs (else_datarefs);
    4042            0 :       return false;
    4043              :     }
    4044         2142 :   blocks[0] = then_bb;
    4045         2142 :   blocks[1] = else_bb;
    4046         2142 :   blocks[2] = join_bb;
    4047         2142 :   renumber_gimple_stmt_uids_in_blocks (blocks, 3);
    4048              : 
    4049              :   /* Check that there are no read-after-write or write-after-write dependencies
    4050              :      in THEN_BB.  */
    4051        13083 :   for (auto ddr : then_ddrs)
    4052              :     {
    4053         7396 :       struct data_reference *dra = DDR_A (ddr);
    4054         7396 :       struct data_reference *drb = DDR_B (ddr);
    4055              : 
    4056         7396 :       if (DDR_ARE_DEPENDENT (ddr) != chrec_known
    4057         7396 :           && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
    4058          827 :                && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
    4059         1566 :               || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
    4060          480 :                   && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
    4061         1086 :               || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
    4062              :         {
    4063          739 :           free_dependence_relations (then_ddrs);
    4064          739 :           free_dependence_relations (else_ddrs);
    4065          739 :           free_data_refs (then_datarefs);
    4066          739 :           free_data_refs (else_datarefs);
    4067          739 :           return false;
    4068              :         }
    4069              :     }
    4070              : 
    4071              :   /* Check that there are no read-after-write or write-after-write dependencies
    4072              :      in ELSE_BB.  */
    4073         8760 :   for (auto ddr : else_ddrs)
    4074              :     {
    4075         4719 :       struct data_reference *dra = DDR_A (ddr);
    4076         4719 :       struct data_reference *drb = DDR_B (ddr);
    4077              : 
    4078         4719 :       if (DDR_ARE_DEPENDENT (ddr) != chrec_known
    4079         4719 :           && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
    4080          401 :                && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
    4081          569 :               || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
    4082          140 :                   && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
    4083          429 :               || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
    4084              :         {
    4085          168 :           free_dependence_relations (then_ddrs);
    4086          168 :           free_dependence_relations (else_ddrs);
    4087          168 :           free_data_refs (then_datarefs);
    4088          168 :           free_data_refs (else_datarefs);
    4089          168 :           return false;
    4090              :         }
    4091              :     }
    4092              : 
    4093              :   /* Sink stores with same LHS.  */
    4094         5328 :   for (auto &store_pair : stores_pairs)
    4095              :     {
    4096         1623 :       then_store = store_pair.first;
    4097         1623 :       else_store = store_pair.second;
    4098         1623 :       res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
    4099              :                                               then_store, else_store, vphi);
    4100         1623 :       ok = ok || res;
    4101              :     }
    4102              : 
    4103         1235 :   free_dependence_relations (then_ddrs);
    4104         1235 :   free_dependence_relations (else_ddrs);
    4105         1235 :   free_data_refs (then_datarefs);
    4106         1235 :   free_data_refs (else_datarefs);
    4107              : 
    4108         1235 :   return ok;
    4109        14513 : }
    4110              : 
    4111              : /* If PHI at MERGE is a "load PHI", PHI <*P, *Q> whose two arguments are
    4112              :    single-use, non-volatile scalar MEM_REF loads reading the same memory state
    4113              :    (same VUSE), factor the load out: introduce P' = PHI <P, Q> and a single
    4114              :    load *P' replacing the PHI.  No speculative load is introduced (the load uses
    4115              :    whichever pointer the taken edge selected).
    4116              :    E0/E1 are the middle bbs to MERGE edges.
    4117              :    EARLY_P is set when the first phiopt is run.
    4118              :    BEFORE_VECT is true if this is before vectorization, where some extra checks
    4119              :    are needed for profitability.
    4120              :    Returns true if a load was factored out.  */
    4121              : 
    4122              : static bool
    4123      1002332 : factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
    4124              :                              bool early_p, bool before_vect)
    4125              : {
    4126              :   /* Factoring out a load during the first phi means we can't
    4127              :      trust if this is inside a loop or not; due to before inlining.  */
    4128      1002332 :   if (early_p)
    4129              :     return false;
    4130              : 
    4131              :   /* Before vectorization, we don't want to factor out loads unless not inside a loop.  */
    4132       801939 :   if (before_vect && bb_loop_depth (merge) != 0)
    4133              :     return false;
    4134              : 
    4135              :   /* Not a virtual operand. */
    4136       834852 :   if (virtual_operand_p (gimple_phi_result (phi))
    4137              :       /* can only handle the merge bb having 2 predecessors.  */
    4138       834852 :       || gimple_phi_num_args (phi) != 2)
    4139              :     return false;
    4140              : 
    4141       172254 :   tree arg0 = gimple_phi_arg_def (phi, e0->dest_idx);
    4142       172254 :   tree arg1 = gimple_phi_arg_def (phi, e1->dest_idx);
    4143              :   /* The load needs to be only used in the phi.  */
    4144       154921 :   if (TREE_CODE (arg0) != SSA_NAME || TREE_CODE (arg1) != SSA_NAME
    4145       313611 :       || !has_single_use (arg0) || !has_single_use (arg1))
    4146              :     return false;
    4147              : 
    4148              :   /* Re-derive the loads and pointers validated by the predicate above.  */
    4149        73734 :   gimple *load0 = SSA_NAME_DEF_STMT (arg0);
    4150        73734 :   gimple *load1 = SSA_NAME_DEF_STMT (arg1);
    4151              : 
    4152              :   /* Load have to need to be in the middle bbs.  */
    4153        73734 :   if (gimple_bb (load0) != e0->src
    4154        73734 :       || gimple_bb (load1) != e1->src)
    4155              :     return false;
    4156              : 
    4157              :   /* The load needs to be a load with NO volatile ops.  */
    4158        91270 :   if (!gimple_assign_load_p (load0) || !gimple_assign_load_p (load1)
    4159       103386 :       || gimple_has_volatile_ops (load0) || gimple_has_volatile_ops (load1))
    4160              :     return false;
    4161              : 
    4162              :   /* Allow for stores/calls before the load.  */
    4163        16654 :   if (gphi *vphi = get_virtual_phi (merge))
    4164              :     {
    4165        24468 :       if (gimple_vuse (load0) != gimple_phi_arg_def (vphi, e0->dest_idx)
    4166        21384 :           || gimple_vuse (load1) != gimple_phi_arg_def (vphi, e1->dest_idx))
    4167              :         return false;
    4168              :     }
    4169              :   /* Sometimes due to not removing dead statements,
    4170              :      a virtual phi does not show up going into an infinite loop
    4171              :      so just reject that case.  */
    4172        13260 :   else if (gimple_vuse (load0) != gimple_vuse (load1))
    4173              :     return false;
    4174              : 
    4175        13533 :   tree ref0 = gimple_assign_rhs1 (load0);
    4176        13533 :   tree ref1 = gimple_assign_rhs1 (load1);
    4177        13533 :   tree index = nullptr;
    4178        13533 :   tree step = nullptr;
    4179        13533 :   tree index2 = nullptr;
    4180        13533 :   bool rev_order = false;
    4181              : 
    4182              :   /* Both must be *P loads of a compatible value type.  The
    4183              :      TBAA alias-ptr type carried by MEM_REF operand 1 need not match; it is
    4184              :      merged the way get_alias_type_for_stmts does when the load is built.  */
    4185        13533 :   if (TREE_CODE (ref0) == MEM_REF)
    4186         5100 :     rev_order = REF_REVERSE_STORAGE_ORDER (ref0);
    4187              :   else
    4188              :     {
    4189         8433 :       if (TREE_CODE (ref0) != TARGET_MEM_REF)
    4190              :         return false;
    4191          315 :       index = TMR_INDEX (ref0);
    4192          315 :       step = TMR_STEP (ref0);
    4193          315 :       index2 = TMR_INDEX2 (ref0);
    4194              :     }
    4195         5415 :   if (TREE_CODE (ref1) == MEM_REF)
    4196              :     {
    4197         4946 :       if (index || step || index2)
    4198              :         return false;
    4199         4946 :       if (rev_order != REF_REVERSE_STORAGE_ORDER (ref1))
    4200              :         return false;
    4201              :     }
    4202              :   else
    4203              :     {
    4204          469 :       if (TREE_CODE (ref1) != TARGET_MEM_REF)
    4205              :         return false;
    4206          325 :       if (rev_order)
    4207              :         return false;
    4208          325 :       if (!safe_operand_equal_p (index, TMR_INDEX (ref1)))
    4209              :         return false;
    4210          312 :       if (!safe_operand_equal_p (step, TMR_STEP (ref1)))
    4211              :         return false;
    4212          312 :       if (!safe_operand_equal_p (index2, TMR_INDEX2 (ref1)))
    4213              :         return false;
    4214              :     }
    4215              : 
    4216         5246 :   if (!types_compatible_p (TREE_TYPE (ref0), TREE_TYPE (ref1)))
    4217              :     return false;
    4218              : 
    4219              :   /* The alignment of the two accesses need to be the same.  */
    4220         5246 :   if (TYPE_ALIGN (TREE_TYPE (ref0)) != TYPE_ALIGN (TREE_TYPE (ref1)))
    4221              :     return false;
    4222              : 
    4223         5000 :   tree p0 = TREE_OPERAND (ref0, 0);
    4224         5000 :   tree p1 = TREE_OPERAND (ref1, 0);
    4225         5000 :   if (!is_factor_profitable (load0, merge, &p0, 1))
    4226              :     return false;
    4227         4982 :   if (!is_factor_profitable (load1, merge, &p1, 1))
    4228              :     return false;
    4229              : 
    4230              :   /* Merge the two arms' TBAA info as get_alias_type_for_stmts does: keep the
    4231              :      common alias-ptr type and dependence clique/base when the arms agree,
    4232              :      otherwise fall back to ptr_type_node (alias-everything) and drop the
    4233              :      clique/base, so the combined load conservatively conflicts with any store
    4234              :      either original arm could.  */
    4235         4982 :   unsigned short clique = MR_DEPENDENCE_CLIQUE (ref0);
    4236         4982 :   unsigned short base = MR_DEPENDENCE_BASE (ref0);
    4237         4982 :   if (clique != MR_DEPENDENCE_CLIQUE (ref1) || base != MR_DEPENDENCE_BASE (ref1))
    4238              :     clique = base = 0;
    4239         4982 :   tree atype = TREE_TYPE (TREE_OPERAND (ref0, 1));
    4240         4982 :   if (!alias_ptr_types_compatible_p (atype, TREE_TYPE (TREE_OPERAND (ref1, 1))))
    4241              :     {
    4242          588 :       atype = ptr_type_node;
    4243          588 :       clique = base = 0;
    4244              :     }
    4245              : 
    4246         4982 :   tree index0 = TREE_OPERAND (ref0, 1);
    4247         4982 :   tree index1 = TREE_OPERAND (ref1, 1);
    4248         4982 :   tree newindex;
    4249         4982 :   gimple_stmt_iterator gsi;
    4250         4982 :   gsi = gsi_after_labels (merge);
    4251              : 
    4252              :   /* Try to handle different indices.  */
    4253         4982 :   if (operand_equal_p (index0, index1))
    4254         4445 :     newindex = fold_convert (atype, index0);
    4255              :   /* FIXME: right now non ssa names with different indices are not handled.  */
    4256          537 :   else if (TREE_CODE (p0) != SSA_NAME || TREE_CODE (p1) != SSA_NAME)
    4257              :     return false;
    4258              :   /* If we have the same base already, just create a phi for the index
    4259              :      and the pointer plus will be done in the merge.  */
    4260           72 :   else if (p0 == p1)
    4261              :     {
    4262           53 :       index0 = fold_convert (sizetype, index0);
    4263           53 :       index1 = fold_convert (sizetype, index1);
    4264           53 :       tree index = make_ssa_name (sizetype);
    4265           53 :       gphi *pphi = create_phi_node (index, merge);
    4266           53 :       add_phi_arg (pphi, index0, e0, gimple_phi_arg_location (phi, e0->dest_idx));
    4267           53 :       add_phi_arg (pphi, index1, e1, gimple_phi_arg_location (phi, e1->dest_idx));
    4268           53 :       p0 = gimple_build (&gsi, true, GSI_SAME_STMT,
    4269              :                          UNKNOWN_LOCATION,
    4270              :                          POINTER_PLUS_EXPR, atype, p0, index);
    4271              :       /* Since we already have the same pointer for both, just set that way.
    4272              :          Also the index offset is already 0 because we just did the add.  */
    4273           53 :       p1 = p0;
    4274           53 :       newindex = build_zero_cst (atype);
    4275           53 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4276              :         {
    4277            2 :           fprintf (dump_file, "new PHI ");
    4278            2 :           print_generic_expr (dump_file, index);
    4279            2 :           fprintf (dump_file,
    4280              :                    " was created for the index.\n");
    4281              :         }
    4282              :     }
    4283              :   else
    4284              :     {
    4285           19 :       gimple_stmt_iterator gsi_index;
    4286              :       /* When the indices are different create 2 new pointers on each
    4287              :          of the middle bb right after the original load.
    4288              :          Note in the case of 0 index, gimple_build just returns
    4289              :          the original pointer.  */
    4290           19 :       gsi_index = gsi_for_stmt (load0);
    4291           19 :       index0 = fold_convert (sizetype, index0);
    4292           19 :       p0 = gimple_build (&gsi_index, false, GSI_SAME_STMT,
    4293              :                          gimple_location (load0),
    4294              :                          POINTER_PLUS_EXPR, atype, p0, index0);
    4295              : 
    4296           19 :       gsi_index = gsi_for_stmt (load1);
    4297           19 :       index1 = fold_convert (sizetype, index1);
    4298           19 :       p1 = gimple_build (&gsi_index, false, GSI_SAME_STMT,
    4299              :                          gimple_location (load1),
    4300              :                          POINTER_PLUS_EXPR, atype, p1, index1);
    4301           19 :       newindex = build_zero_cst (atype);
    4302           19 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4303              :         {
    4304            1 :           fprintf (dump_file, "new ptrs ");
    4305            1 :           print_generic_expr (dump_file, p0);
    4306            1 :           fprintf (dump_file, " and ");
    4307            1 :           print_generic_expr (dump_file, p1);
    4308            1 :           fprintf (dump_file,
    4309              :                    " was created due to different offsets.\n");
    4310              :         }
    4311              :     }
    4312              : 
    4313         4517 :   tree newptr;
    4314         4517 :   if (p0 != p1)
    4315              :     {
    4316              :       /* We can't factor out a non-ssa named based load
    4317              :          as it might cause a variable not taken an
    4318              :          address to become needing the address taken.
    4319              :          An example is in go.
    4320              :          Were we produce:
    4321              :          _24 = PHI <&crypto/tls.cipherSuitesPreferenceOrder(36), &crypto/tls.cipherSuitesPreferenceOrderNoAES(37)>
    4322              :          And &crypto/tls.cipherSuitesPreferenceOrder address bit was not set.
    4323              :          FIXME: Refine to check ADDRESSABLE bit.  */
    4324         3065 :       if (TREE_CODE (p0) != SSA_NAME || TREE_CODE (p1) != SSA_NAME)
    4325              :         return false;
    4326              :       // Incompatible address spaces or differnt function pointers could show up here.
    4327          343 :       if (!types_compatible_p (TREE_TYPE (p0), TREE_TYPE (p1)))
    4328              :         return false;
    4329              :       /* Build P' = PHI <P, Q> and the single load result = *P'.  */
    4330          325 :       newptr = make_ssa_name (TREE_TYPE (p0));
    4331          325 :       gphi *pphi = create_phi_node (newptr, merge);
    4332          325 :       add_phi_arg (pphi, p0, e0, gimple_phi_arg_location (phi, e0->dest_idx));
    4333          325 :       add_phi_arg (pphi, p1, e1, gimple_phi_arg_location (phi, e1->dest_idx));
    4334              :     }
    4335              :    else
    4336              :      newptr = p0;
    4337              : 
    4338              :   /* Build the combined load RES = *PTR, reusing the PHI result so any range
    4339              :      info on it is preserved (as factor_out_conditional_operation does).  */
    4340         1777 :   tree nref;
    4341         1777 :   if (index || step || index2)
    4342           24 :     nref = build5 (TARGET_MEM_REF, TREE_TYPE (ref0), newptr,
    4343              :                    newindex, index, step, index2);
    4344              :   else
    4345              :     {
    4346         1753 :       nref = build2 (MEM_REF, TREE_TYPE (ref0), newptr, newindex);
    4347         1753 :       REF_REVERSE_STORAGE_ORDER (nref) = rev_order;
    4348              :     }
    4349         1777 :   MR_DEPENDENCE_CLIQUE (nref) = clique;
    4350         1777 :   MR_DEPENDENCE_BASE (nref) = base;
    4351         1777 :   tree res = gimple_phi_result (phi);
    4352         1777 :   gassign *load = gimple_build_assign (res, nref);
    4353         1777 :   if (gphi *vphi = get_virtual_phi (merge))
    4354         1435 :     gimple_set_vuse (load, gimple_phi_result (vphi));
    4355              :   else
    4356          684 :     gimple_set_vuse (load, gimple_vuse (load0));
    4357         1777 :   gsi_insert_before (&gsi, load, GSI_SAME_STMT);
    4358              : 
    4359              :   /* RES is now defined by the load; drop the original PHI.  */
    4360         1777 :   gsi = gsi_for_stmt (phi);
    4361         1777 :   remove_phi_node (&gsi, false);
    4362              : 
    4363              :   /* The two arm loads are now dead.  */
    4364         1777 :   gsi = gsi_for_stmt (load0);
    4365         1777 :   gsi_remove (&gsi, true);
    4366         1777 :   release_defs (load0);
    4367         1777 :   gsi = gsi_for_stmt (load1);
    4368         1777 :   gsi_remove (&gsi, true);
    4369         1777 :   release_defs (load1);
    4370              : 
    4371         1777 :   if (dump_file && (dump_flags & TDF_DETAILS))
    4372              :     {
    4373           11 :       fprintf (dump_file, "PHI ");
    4374           11 :       print_generic_expr (dump_file, res);
    4375           11 :       fprintf (dump_file,
    4376              :                " changed to factor out load from COND_EXPR.\n");
    4377           11 :       if (p0 != p1)
    4378              :         {
    4379            9 :           fprintf (dump_file, "new PHI ");
    4380            9 :           print_generic_expr (dump_file, newptr);
    4381            9 :           fprintf (dump_file,
    4382              :                    " was created for the pointers.\n");
    4383              :         }
    4384              :     }
    4385              : 
    4386         1777 :   statistics_counter_event (cfun, "factored load out of COND_EXPR", 1);
    4387         1777 :   return true;
    4388              : }
    4389              : 
    4390              : /* Factor out operations and stores from the phi of the MERGE block coming
    4391              :    in from the edges E1 and E2 if possible. COND_STMT is the conditional
    4392              :    statement of the origin block. DIAMOND_P says that both E1 and E2 src
    4393              :    are not the origin block but rather 2 middle BBs. EARLY_P is true if
    4394              :    this was the early phi-opt.
    4395              :    Returns true if a factoring happened. */
    4396              : static bool
    4397      2560789 : factor_out_all (edge e1, edge e2, basic_block merge,
    4398              :                 gcond *cond_stmt, bool diamond_p, bool early_p)
    4399              : {
    4400      2560789 :   bool changed = false;
    4401      2560789 :   bool do_over;
    4402      2560789 :   basic_block bb1 = e1->src;
    4403      2560789 :   basic_block bb2 = e2->src;
    4404      2532949 :   do
    4405              :     {
    4406      2604899 :       do_over = false;
    4407      2604899 :       if (diamond_p && get_virtual_phi (merge))
    4408              :         {
    4409       720163 :           if (cond_if_else_store_replacement_limited (bb1, bb2, merge))
    4410              :             {
    4411        13497 :               changed = true;
    4412        13497 :               do_over = true;
    4413        14287 :               continue;
    4414              :             }
    4415              :         }
    4416      2591402 :       if (!single_pred_p (bb1))
    4417              :         break;
    4418      1735430 :       if (!diamond_p && get_virtual_phi (merge)
    4419      3555299 :           && cond_store_replacement_limited (bb1, merge, bb2,
    4420              :                                              e1, e2, false))
    4421              :         {
    4422          790 :           changed = true;
    4423          790 :           do_over = true;
    4424          790 :           continue;
    4425              :         }
    4426      2518662 :       gphi_iterator gsi;
    4427      5585164 :       for (gsi = gsi_start_phis (merge); !gsi_end_p (gsi); gsi_next (&gsi))
    4428              :         {
    4429      3096325 :           gphi *phi = *gsi;
    4430              :           /* Conditional load elimination can only be on a diamond.  */
    4431      3096325 :           if ((diamond_p
    4432      1002332 :                && factor_out_conditional_load (e1, e2, merge, phi, early_p,
    4433              :                                                !fold_before_rtl_expansion_p ()))
    4434      4096880 :               || factor_out_conditional_operation (e1, e2, merge, phi,
    4435              :                                                    cond_stmt, early_p))
    4436              :             {
    4437              :               changed = true;
    4438              :               do_over = true;
    4439              :               break;
    4440              :             }
    4441              :         }
    4442              :     } while (do_over);
    4443      2560789 :   return changed;
    4444              : }
    4445              : 
    4446              : /* Return TRUE if STMT has a VUSE whose corresponding VDEF is in BB.  */
    4447              : 
    4448              : static bool
    4449        12134 : local_mem_dependence (gimple *stmt, basic_block bb)
    4450              : {
    4451        24268 :   tree vuse = gimple_vuse (stmt);
    4452        12134 :   gimple *def;
    4453              : 
    4454        12134 :   if (!vuse)
    4455              :     return false;
    4456              : 
    4457        12134 :   def = SSA_NAME_DEF_STMT (vuse);
    4458        12134 :   return (def && gimple_bb (def) == bb);
    4459              : }
    4460              : 
    4461              : /* Given a "diamond" control-flow pattern where BB0 tests a condition,
    4462              :    BB1 and BB2 are "then" and "else" blocks dependent on this test,
    4463              :    and BB3 rejoins control flow following BB1 and BB2, look for
    4464              :    opportunities to hoist loads as follows.  If BB3 contains a PHI of
    4465              :    two loads, one each occurring in BB1 and BB2, and the loads are
    4466              :    provably of adjacent fields in the same structure, then move both
    4467              :    loads into BB0.  Of course this can only be done if there are no
    4468              :    dependencies preventing such motion.
    4469              : 
    4470              :    One of the hoisted loads will always be speculative, so the
    4471              :    transformation is currently conservative:
    4472              : 
    4473              :     - The fields must be strictly adjacent.
    4474              :     - The two fields must occupy a single memory block that is
    4475              :       guaranteed to not cross a page boundary.
    4476              : 
    4477              :     The last is difficult to prove, as such memory blocks should be
    4478              :     aligned on the minimum of the stack alignment boundary and the
    4479              :     alignment guaranteed by heap allocation interfaces.  Thus we rely
    4480              :     on a parameter for the alignment value.
    4481              : 
    4482              :     Provided a good value is used for the last case, the first
    4483              :     restriction could possibly be relaxed.  */
    4484              : 
    4485              : static void
    4486       603958 : hoist_adjacent_loads (basic_block bb0, basic_block bb1,
    4487              :                       basic_block bb2, basic_block bb3)
    4488              : {
    4489       603958 :   unsigned HOST_WIDE_INT param_align = param_l1_cache_line_size;
    4490       603958 :   unsigned HOST_WIDE_INT param_align_bits = param_align * BITS_PER_UNIT;
    4491       603958 :   gphi_iterator gsi;
    4492              : 
    4493              :   /* Walk the phis in bb3 looking for an opportunity.  We are looking
    4494              :      for phis of two SSA names, one each of which is defined in bb1 and
    4495              :      bb2.  */
    4496      1359000 :   for (gsi = gsi_start_phis (bb3); !gsi_end_p (gsi); gsi_next (&gsi))
    4497              :     {
    4498       755042 :       gphi *phi_stmt = gsi.phi ();
    4499       755042 :       gimple *def1, *def2;
    4500       755042 :       tree arg1, arg2, ref1, ref2, field1, field2;
    4501       755042 :       tree tree_offset1, tree_offset2, tree_size2, next;
    4502       755042 :       unsigned HOST_WIDE_INT offset1, offset2, size2, align1;
    4503       755042 :       gimple_stmt_iterator gsi2;
    4504       755042 :       basic_block bb_for_def1, bb_for_def2;
    4505              : 
    4506       755042 :       if (gimple_phi_num_args (phi_stmt) != 2
    4507      1510084 :           || virtual_operand_p (gimple_phi_result (phi_stmt)))
    4508       748975 :         continue;
    4509              : 
    4510       193754 :       arg1 = gimple_phi_arg_def (phi_stmt, 0);
    4511       193754 :       arg2 = gimple_phi_arg_def (phi_stmt, 1);
    4512              : 
    4513       227007 :       if (TREE_CODE (arg1) != SSA_NAME
    4514       176603 :           || TREE_CODE (arg2) != SSA_NAME
    4515       161770 :           || SSA_NAME_IS_DEFAULT_DEF (arg1)
    4516       355194 :           || SSA_NAME_IS_DEFAULT_DEF (arg2))
    4517        33253 :         continue;
    4518              : 
    4519       160501 :       def1 = SSA_NAME_DEF_STMT (arg1);
    4520       160501 :       def2 = SSA_NAME_DEF_STMT (arg2);
    4521              : 
    4522       160501 :       if ((gimple_bb (def1) != bb1 || gimple_bb (def2) != bb2)
    4523       175033 :           && (gimple_bb (def2) != bb1 || gimple_bb (def1) != bb2))
    4524        41492 :         continue;
    4525              : 
    4526              :       /* Check the mode of the arguments to be sure a conditional move
    4527              :          can be generated for it.  */
    4528       238018 :       if (optab_handler (movcc_optab, TYPE_MODE (TREE_TYPE (arg1)))
    4529              :           == CODE_FOR_nothing)
    4530         5260 :         continue;
    4531              : 
    4532              :       /* Both statements must be assignments whose RHS is a COMPONENT_REF.  */
    4533       113749 :       if (!gimple_assign_single_p (def1)
    4534        53315 :           || !gimple_assign_single_p (def2)
    4535        71260 :           || gimple_has_volatile_ops (def1)
    4536       185003 :           || gimple_has_volatile_ops (def2))
    4537        78122 :         continue;
    4538              : 
    4539        35627 :       ref1 = gimple_assign_rhs1 (def1);
    4540        35627 :       ref2 = gimple_assign_rhs1 (def2);
    4541              : 
    4542        35627 :       if (TREE_CODE (ref1) != COMPONENT_REF
    4543        24145 :           || TREE_CODE (ref2) != COMPONENT_REF)
    4544        11605 :         continue;
    4545              : 
    4546              :       /* The zeroth operand of the two component references must be
    4547              :          identical.  It is not sufficient to compare get_base_address of
    4548              :          the two references, because this could allow for different
    4549              :          elements of the same array in the two trees.  It is not safe to
    4550              :          assume that the existence of one array element implies the
    4551              :          existence of a different one.  */
    4552        24022 :       if (!operand_equal_p (TREE_OPERAND (ref1, 0), TREE_OPERAND (ref2, 0), 0))
    4553         4589 :         continue;
    4554              : 
    4555        19433 :       field1 = TREE_OPERAND (ref1, 1);
    4556        19433 :       field2 = TREE_OPERAND (ref2, 1);
    4557              : 
    4558              :       /* Check for field adjacency, and ensure field1 comes first.  */
    4559        19433 :       for (next = DECL_CHAIN (field1);
    4560        33603 :            next && TREE_CODE (next) != FIELD_DECL;
    4561        14170 :            next = DECL_CHAIN (next))
    4562              :         ;
    4563              : 
    4564        19433 :       if (next != field2)
    4565              :         {
    4566        15825 :           for (next = DECL_CHAIN (field2);
    4567        17896 :                next && TREE_CODE (next) != FIELD_DECL;
    4568         2071 :                next = DECL_CHAIN (next))
    4569              :             ;
    4570              : 
    4571        15825 :           if (next != field1)
    4572        13366 :             continue;
    4573              : 
    4574              :           std::swap (field1, field2);
    4575              :           std::swap (def1, def2);
    4576              :         }
    4577              : 
    4578         6067 :       bb_for_def1 = gimple_bb (def1);
    4579         6067 :       bb_for_def2 = gimple_bb (def2);
    4580              : 
    4581              :       /* Check for proper alignment of the first field.  */
    4582         6067 :       tree_offset1 = bit_position (field1);
    4583         6067 :       tree_offset2 = bit_position (field2);
    4584         6067 :       tree_size2 = DECL_SIZE (field2);
    4585              : 
    4586         6067 :       if (!tree_fits_uhwi_p (tree_offset1)
    4587         6067 :           || !tree_fits_uhwi_p (tree_offset2)
    4588         6067 :           || !tree_fits_uhwi_p (tree_size2))
    4589            0 :         continue;
    4590              : 
    4591         6067 :       offset1 = tree_to_uhwi (tree_offset1);
    4592         6067 :       offset2 = tree_to_uhwi (tree_offset2);
    4593         6067 :       size2 = tree_to_uhwi (tree_size2);
    4594         6067 :       align1 = DECL_ALIGN (field1) % param_align_bits;
    4595              : 
    4596         6067 :       if (offset1 % BITS_PER_UNIT != 0)
    4597            0 :         continue;
    4598              : 
    4599              :       /* For profitability, the two field references should fit within
    4600              :          a single cache line.  */
    4601         6067 :       if (align1 + offset2 - offset1 + size2 > param_align_bits)
    4602            0 :         continue;
    4603              : 
    4604              :       /* The two expressions cannot be dependent upon vdefs defined
    4605              :          in bb1/bb2.  */
    4606         6067 :       if (local_mem_dependence (def1, bb_for_def1)
    4607         6067 :           || local_mem_dependence (def2, bb_for_def2))
    4608            0 :         continue;
    4609              : 
    4610              :       /* The conditions are satisfied; hoist the loads from bb1 and bb2 into
    4611              :          bb0.  We hoist the first one first so that a cache miss is handled
    4612              :          efficiently regardless of hardware cache-fill policy.  */
    4613         6067 :       gsi2 = gsi_for_stmt (def1);
    4614         6067 :       gsi_move_to_bb_end (&gsi2, bb0);
    4615         6067 :       gsi2 = gsi_for_stmt (def2);
    4616         6067 :       gsi_move_to_bb_end (&gsi2, bb0);
    4617         6067 :       statistics_counter_event (cfun, "hoisted loads", 1);
    4618              : 
    4619         6067 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4620              :         {
    4621            0 :           fprintf (dump_file,
    4622              :                    "\nHoisting adjacent loads from %d and %d into %d: \n",
    4623              :                    bb_for_def1->index, bb_for_def2->index, bb0->index);
    4624            0 :           print_gimple_stmt (dump_file, def1, 0, TDF_VOPS|TDF_MEMSYMS);
    4625            0 :           print_gimple_stmt (dump_file, def2, 0, TDF_VOPS|TDF_MEMSYMS);
    4626              :         }
    4627              :     }
    4628       603958 : }
    4629              : 
    4630              : /* Determine whether we should attempt to hoist adjacent loads out of
    4631              :    diamond patterns in pass_phiopt.  Always hoist loads if
    4632              :    -fhoist-adjacent-loads is specified and the target machine has
    4633              :    both a conditional move instruction and a defined cache line size.  */
    4634              : 
    4635              : static bool
    4636      3180751 : gate_hoist_loads (void)
    4637              : {
    4638      3180751 :   return (flag_hoist_adjacent_loads == 1
    4639      3180751 :           && param_l1_cache_line_size
    4640            0 :           && HAVE_conditional_move);
    4641              : }
    4642              : 
    4643              : template <class func_type>
    4644              : static void
    4645      6779922 : execute_over_cond_phis (func_type func)
    4646              : {
    4647              :   unsigned n, i;
    4648              :   basic_block *bb_order;
    4649              :   basic_block bb;
    4650              :   /* Search every basic block for COND_EXPR we may be able to optimize.
    4651              : 
    4652              :      We walk the blocks in order that guarantees that a block with
    4653              :      a single predecessor is processed before the predecessor.
    4654              :      This ensures that we collapse inner ifs before visiting the
    4655              :      outer ones, and also that we do not try to visit a removed
    4656              :      block.  */
    4657      6779922 :   bb_order = single_pred_before_succ_order ();
    4658      6779922 :   n = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
    4659              : 
    4660     60935781 :   for (i = 0; i < n; i++)
    4661              :     {
    4662              :       basic_block bb1, bb2;
    4663              :       edge e1, e2;
    4664     54155859 :       bool diamond_p = false;
    4665              : 
    4666     54155859 :       bb = bb_order[i];
    4667              : 
    4668              :       /* Check to see if the last statement is a GIMPLE_COND.  */
    4669     54155859 :       gcond *cond_stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
    4670     32371755 :       if (!cond_stmt)
    4671     54155859 :         continue;
    4672              : 
    4673     21784104 :       e1 = EDGE_SUCC (bb, 0);
    4674     21784104 :       bb1 = e1->dest;
    4675     21784104 :       e2 = EDGE_SUCC (bb, 1);
    4676     21784104 :       bb2 = e2->dest;
    4677              : 
    4678              :       /* We cannot do the optimization on abnormal edges.  */
    4679     21784104 :       if ((e1->flags & EDGE_ABNORMAL) != 0
    4680     21784104 :           || (e2->flags & EDGE_ABNORMAL) != 0)
    4681            0 :         continue;
    4682              : 
    4683              :       /* If either bb1's succ or bb2 or bb2's succ is non NULL.  */
    4684     21784104 :       if (EDGE_COUNT (bb1->succs) == 0
    4685     20304820 :           || EDGE_COUNT (bb2->succs) == 0)
    4686      5001684 :         continue;
    4687              : 
    4688              :       /* Find the bb which is the fall through to the other.  */
    4689     16782420 :       if (EDGE_SUCC (bb1, 0)->dest == bb2)
    4690              :         ;
    4691     14252024 :       else if (EDGE_SUCC (bb2, 0)->dest == bb1)
    4692              :         {
    4693              :           std::swap (bb1, bb2);
    4694              :           std::swap (e1, e2);
    4695              :         }
    4696     10850420 :       else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest
    4697     12429536 :                && single_succ_p (bb2))
    4698              :         {
    4699      1579116 :           diamond_p = true;
    4700      1579116 :           e2 = EDGE_SUCC (bb2, 0);
    4701              :           /* Make sure bb2 is just a fall through. */
    4702      1579116 :           if ((e2->flags & EDGE_FALLTHRU) == 0)
    4703        52259 :             continue;
    4704              :         }
    4705              :       else
    4706     10850420 :         continue;
    4707              : 
    4708      5879741 :       e1 = EDGE_SUCC (bb1, 0);
    4709              : 
    4710              :       /* Make sure that bb1 is just a fall through.  */
    4711      5879741 :       if (!single_succ_p (bb1)
    4712      5879741 :           || (e1->flags & EDGE_FALLTHRU) == 0)
    4713      1390623 :         continue;
    4714              : 
    4715      4489118 :       func (bb, bb1, bb2, e1, e2, diamond_p, cond_stmt);
    4716              :     }
    4717      6779922 :   free (bb_order);
    4718      6779922 : }
    4719              : 
    4720              : /* This pass tries to replaces an if-then-else block with an
    4721              :    assignment.  We have different kinds of transformations.
    4722              :    Some of these transformations are also performed by the ifcvt
    4723              :    RTL optimizer.
    4724              : 
    4725              :    PHI-OPT using Match-and-simplify infrastructure
    4726              :    -----------------------
    4727              : 
    4728              :    The PHI-OPT pass will try to use match-and-simplify infrastructure
    4729              :    (gimple_simplify) to do transformations. This is implemented in
    4730              :    match_simplify_replacement.
    4731              : 
    4732              :    The way it works is it replaces:
    4733              :      bb0:
    4734              :       if (cond) goto bb2; else goto bb1;
    4735              :      bb1:
    4736              :      bb2:
    4737              :       x = PHI <a (bb1), b (bb0), ...>;
    4738              : 
    4739              :    with a statement if it gets simplified from `cond ? b : a`.
    4740              : 
    4741              :      bb0:
    4742              :       x1 = cond ? b : a;
    4743              :      bb2:
    4744              :       x = PHI <a (bb1), x1 (bb0), ...>;
    4745              :    Bb1 might be removed as it becomes unreachable when doing the replacement.
    4746              :    Though bb1 does not have to be considered a forwarding basic block from bb0.
    4747              : 
    4748              :    Will try to see if `(!cond) ? a : b` gets simplified (iff !cond simplifies);
    4749              :    this is done not to have an explosion of patterns in match.pd.
    4750              :    Note bb1 does not need to be completely empty, it can contain
    4751              :    one statement which is known not to trap.
    4752              : 
    4753              :    It also can handle the case where we have two forwarding bbs (diamond):
    4754              :      bb0:
    4755              :       if (cond) goto bb2; else goto bb1;
    4756              :      bb1: goto bb3;
    4757              :      bb2: goto bb3;
    4758              :      bb3:
    4759              :       x = PHI <a (bb1), b (bb2), ...>;
    4760              :    And that is replaced with a statement if it is simplified
    4761              :    from `cond ? b : a`.
    4762              :    Again bb1 and bb2 does not have to be completely empty but
    4763              :    each can contain one statement which is known not to trap.
    4764              :    But in this case bb1/bb2 can only be forwarding basic blocks.
    4765              : 
    4766              :    This fully replaces the old "Conditional Replacement",
    4767              :    "ABS Replacement" and "MIN/MAX Replacement" transformations as they are now
    4768              :    implemented in match.pd.
    4769              : 
    4770              :    Value Replacement
    4771              :    -----------------
    4772              : 
    4773              :    This transformation, implemented in value_replacement, replaces
    4774              : 
    4775              :      bb0:
    4776              :        if (a != b) goto bb2; else goto bb1;
    4777              :      bb1:
    4778              :      bb2:
    4779              :        x = PHI <a (bb1), b (bb0), ...>;
    4780              : 
    4781              :    with
    4782              : 
    4783              :      bb0:
    4784              :      bb2:
    4785              :        x = PHI <b (bb0), ...>;
    4786              : 
    4787              :    This opportunity can sometimes occur as a result of other
    4788              :    optimizations.
    4789              : 
    4790              : 
    4791              :    Another case caught by value replacement looks like this:
    4792              : 
    4793              :      bb0:
    4794              :        t1 = a == CONST;
    4795              :        t2 = b > c;
    4796              :        t3 = t1 & t2;
    4797              :        if (t3 != 0) goto bb1; else goto bb2;
    4798              :      bb1:
    4799              :      bb2:
    4800              :        x = PHI (CONST, a)
    4801              : 
    4802              :    Gets replaced with:
    4803              :      bb0:
    4804              :      bb2:
    4805              :        t1 = a == CONST;
    4806              :        t2 = b > c;
    4807              :        t3 = t1 & t2;
    4808              :        x = a;
    4809              : 
    4810              : 
    4811              :    This pass also performs a fifth transformation of a slightly different
    4812              :    flavor.
    4813              : 
    4814              :    Factor operations in COND_EXPR
    4815              :    ------------------------------
    4816              : 
    4817              :    This transformation factors the unary operations out of COND_EXPR with
    4818              :    factor_out_conditional_operation.
    4819              : 
    4820              :    For example:
    4821              :    if (a <= CST) goto <bb 3>; else goto <bb 4>;
    4822              :    <bb 3>:
    4823              :    tmp = (int) a;
    4824              :    <bb 4>:
    4825              :    tmp = PHI <tmp, CST>
    4826              : 
    4827              :    Into:
    4828              :    if (a <= CST) goto <bb 3>; else goto <bb 4>;
    4829              :    <bb 3>:
    4830              :    <bb 4>:
    4831              :    a = PHI <a, CST>
    4832              :    tmp = (int) a;
    4833              : 
    4834              :    Adjacent Load Hoisting
    4835              :    ----------------------
    4836              : 
    4837              :    This transformation replaces
    4838              : 
    4839              :      bb0:
    4840              :        if (...) goto bb2; else goto bb1;
    4841              :      bb1:
    4842              :        x1 = (<expr>).field1;
    4843              :        goto bb3;
    4844              :      bb2:
    4845              :        x2 = (<expr>).field2;
    4846              :      bb3:
    4847              :        # x = PHI <x1, x2>;
    4848              : 
    4849              :    with
    4850              : 
    4851              :      bb0:
    4852              :        x1 = (<expr>).field1;
    4853              :        x2 = (<expr>).field2;
    4854              :        if (...) goto bb2; else goto bb1;
    4855              :      bb1:
    4856              :        goto bb3;
    4857              :      bb2:
    4858              :      bb3:
    4859              :        # x = PHI <x1, x2>;
    4860              : 
    4861              :    The purpose of this transformation is to enable generation of conditional
    4862              :    move instructions such as Intel CMOVE or PowerPC ISEL.  Because one of
    4863              :    the loads is speculative, the transformation is restricted to very
    4864              :    specific cases to avoid introducing a page fault.  We are looking for
    4865              :    the common idiom:
    4866              : 
    4867              :      if (...)
    4868              :        x = y->left;
    4869              :      else
    4870              :        x = y->right;
    4871              : 
    4872              :    where left and right are typically adjacent pointers in a tree structure.  */
    4873              : 
    4874              : namespace {
    4875              : 
    4876              : const pass_data pass_data_phiopt =
    4877              : {
    4878              :   GIMPLE_PASS, /* type */
    4879              :   "phiopt", /* name */
    4880              :   OPTGROUP_NONE, /* optinfo_flags */
    4881              :   TV_TREE_PHIOPT, /* tv_id */
    4882              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
    4883              :   0, /* properties_provided */
    4884              :   0, /* properties_destroyed */
    4885              :   0, /* todo_flags_start */
    4886              :   0, /* todo_flags_finish */
    4887              : };
    4888              : 
    4889              : class pass_phiopt : public gimple_opt_pass
    4890              : {
    4891              : public:
    4892      1176784 :   pass_phiopt (gcc::context *ctxt)
    4893      2353568 :     : gimple_opt_pass (pass_data_phiopt, ctxt), early_p (false)
    4894              :   {}
    4895              : 
    4896              :   /* opt_pass methods: */
    4897       882588 :   opt_pass * clone () final override { return new pass_phiopt (m_ctxt); }
    4898      1176784 :   void set_pass_param (unsigned n, bool param) final override
    4899              :     {
    4900      1176784 :       gcc_assert (n == 0);
    4901      1176784 :       early_p = param;
    4902      1176784 :     }
    4903      5722910 :   bool gate (function *) final override { return flag_ssa_phiopt; }
    4904              :   unsigned int execute (function *) final override;
    4905              : 
    4906              : private:
    4907              :   bool early_p;
    4908              : }; // class pass_phiopt
    4909              : 
    4910              : } // anon namespace
    4911              : 
    4912              : gimple_opt_pass *
    4913       294196 : make_pass_phiopt (gcc::context *ctxt)
    4914              : {
    4915       294196 :   return new pass_phiopt (ctxt);
    4916              : }
    4917              : 
    4918              : unsigned int
    4919      5719639 : pass_phiopt::execute (function *)
    4920              : {
    4921      5719639 :   bool do_hoist_loads = !early_p ? gate_hoist_loads () : false;
    4922      5719639 :   bool cfgchanged = false;
    4923              : 
    4924      5719639 :   calculate_dominance_info (CDI_DOMINATORS);
    4925      5719639 :   mark_ssa_maybe_undefs ();
    4926              : 
    4927      9267287 :   auto phiopt_exec = [&] (basic_block bb, basic_block bb1,
    4928              :                           basic_block bb2, edge e1, edge e2,
    4929              :                           bool diamond_p, gcond *cond_stmt)
    4930              :     {
    4931      3547648 :       if (diamond_p)
    4932              :         {
    4933      1132436 :           basic_block bb3 = e1->dest;
    4934              : 
    4935      1132436 :           if (!single_pred_p (bb1)
    4936      2204600 :               || !single_pred_p (bb2))
    4937      3547648 :             return;
    4938              : 
    4939      1011008 :           if (do_hoist_loads
    4940       794428 :               && !FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond_stmt)))
    4941       786274 :               && EDGE_COUNT (bb->succs) == 2
    4942       786274 :               && EDGE_COUNT (bb3->preds) == 2
    4943              :               /* If one edge or the other is dominant, a conditional move
    4944              :                  is likely to perform worse than the well-predicted branch.  */
    4945       608459 :               && !predictable_edge_p (EDGE_SUCC (bb, 0))
    4946      1614966 :               && !predictable_edge_p (EDGE_SUCC (bb, 1)))
    4947       603958 :             hoist_adjacent_loads (bb, bb1, bb2, bb3);
    4948              :         }
    4949              : 
    4950      1011008 :       gimple_stmt_iterator gsi;
    4951              : 
    4952              :       /* Check that we're looking for nested phis.  */
    4953      1011008 :       basic_block merge = diamond_p ? EDGE_SUCC (bb2, 0)->dest : bb2;
    4954              : 
    4955              :       /* Factor out operations from the phi if possible. */
    4956      3426220 :       if (EDGE_COUNT (merge->preds) == 2
    4957      3426220 :           && !optimize_debug && factor_out_all (e1, e2, merge, cond_stmt, diamond_p, early_p))
    4958        37077 :         cfgchanged = true;
    4959              : 
    4960      3426220 :       gimple_seq phis = phi_nodes (merge);
    4961              : 
    4962      3426220 :       if (gimple_seq_empty_p (phis))
    4963              :         return;
    4964              : 
    4965              :       /* Value replacement can work with more than one PHI
    4966              :          so try that first. */
    4967      3411912 :       if (!early_p && !diamond_p)
    4968      4286839 :         for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
    4969              :           {
    4970      2497235 :             gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
    4971      2497235 :             tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
    4972      2497235 :             tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
    4973      2497235 :             if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1) == 2)
    4974              :               {
    4975         1963 :                 cfgchanged = true;
    4976         1963 :                 return;
    4977              :               }
    4978              :           }
    4979              : 
    4980      3409949 :       gphi *phi = single_non_singleton_phi_for_edges (phis, e1, e2);
    4981      3409949 :       if (!phi)
    4982              :         return;
    4983              : 
    4984       868186 :       tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
    4985       868186 :       tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
    4986              : 
    4987              :       /* Something is wrong if we cannot find the arguments in the PHI
    4988              :           node.  */
    4989       868186 :       gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
    4990              : 
    4991              : 
    4992              :       /* Do the replacement of conditional if it can be done.  */
    4993       868186 :       if (match_simplify_replacement (bb, bb1, bb2, e1, e2, phi,
    4994              :                                       arg0, arg1, early_p, diamond_p))
    4995        96106 :         cfgchanged = true;
    4996       772080 :       else if (comparison_combine (bb, bb1, bb2, e1, e2, phi,
    4997              :                                    arg0, arg1, diamond_p))
    4998           16 :         cfgchanged = true;
    4999       772064 :       else if (!early_p
    5000       511299 :                && !diamond_p
    5001       477613 :                && single_pred_p (bb1)
    5002      1229701 :                && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2,
    5003              :                                                         phi, arg0, arg1))
    5004           13 :         cfgchanged = true;
    5005       772051 :       else if (single_pred_p (bb1)
    5006       721361 :                && !diamond_p
    5007      1430209 :                && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
    5008         2330 :         cfgchanged = true;
    5009      5719639 :     };
    5010              : 
    5011      5719639 :   execute_over_cond_phis (phiopt_exec);
    5012              : 
    5013      5719639 :   if (cfgchanged)
    5014        90563 :     return TODO_cleanup_cfg;
    5015              :   return 0;
    5016              : }
    5017              : 
    5018              : /* This pass tries to transform conditional stores into unconditional
    5019              :    ones, enabling further simplifications with the simpler then and else
    5020              :    blocks.  In particular it replaces this:
    5021              : 
    5022              :      bb0:
    5023              :        if (cond) goto bb2; else goto bb1;
    5024              :      bb1:
    5025              :        *p = RHS;
    5026              :      bb2:
    5027              : 
    5028              :    with
    5029              : 
    5030              :      bb0:
    5031              :        if (cond) goto bb1; else goto bb2;
    5032              :      bb1:
    5033              :        condtmp' = *p;
    5034              :      bb2:
    5035              :        condtmp = PHI <RHS, condtmp'>
    5036              :        *p = condtmp;
    5037              : 
    5038              :    This transformation can only be done under several constraints,
    5039              :    documented below.  It also replaces:
    5040              : 
    5041              :      bb0:
    5042              :        if (cond) goto bb2; else goto bb1;
    5043              :      bb1:
    5044              :        *p = RHS1;
    5045              :        goto bb3;
    5046              :      bb2:
    5047              :        *p = RHS2;
    5048              :      bb3:
    5049              : 
    5050              :    with
    5051              : 
    5052              :      bb0:
    5053              :        if (cond) goto bb3; else goto bb1;
    5054              :      bb1:
    5055              :      bb3:
    5056              :        condtmp = PHI <RHS1, RHS2>
    5057              :        *p = condtmp;  */
    5058              : 
    5059              : namespace {
    5060              : 
    5061              : const pass_data pass_data_cselim =
    5062              : {
    5063              :   GIMPLE_PASS, /* type */
    5064              :   "cselim", /* name */
    5065              :   OPTGROUP_NONE, /* optinfo_flags */
    5066              :   TV_TREE_PHIOPT, /* tv_id */
    5067              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
    5068              :   0, /* properties_provided */
    5069              :   0, /* properties_destroyed */
    5070              :   0, /* todo_flags_start */
    5071              :   0, /* todo_flags_finish */
    5072              : };
    5073              : 
    5074              : class pass_cselim : public gimple_opt_pass
    5075              : {
    5076              : public:
    5077       294196 :   pass_cselim (gcc::context *ctxt)
    5078       588392 :     : gimple_opt_pass (pass_data_cselim, ctxt)
    5079              :   {}
    5080              : 
    5081              :   /* opt_pass methods: */
    5082      1060389 :   bool gate (function *) final override { return flag_tree_cselim; }
    5083              :   unsigned int execute (function *) final override;
    5084              : 
    5085              : }; // class pass_cselim
    5086              : 
    5087              : } // anon namespace
    5088              : 
    5089              : gimple_opt_pass *
    5090       294196 : make_pass_cselim (gcc::context *ctxt)
    5091              : {
    5092       294196 :   return new pass_cselim (ctxt);
    5093              : }
    5094              : 
    5095              : unsigned int
    5096      1060283 : pass_cselim::execute (function *)
    5097              : {
    5098      1060283 :   bool cfgchanged = false;
    5099      1060283 :   hash_set<tree> *nontrap = 0;
    5100      1060283 :   unsigned todo = 0;
    5101              : 
    5102              :   /* ???  We are not interested in loop related info, but the following
    5103              :      will create it, ICEing as we didn't init loops with pre-headers.
    5104              :      An interfacing issue of find_data_references_in_bb.  */
    5105      1060283 :   loop_optimizer_init (LOOPS_NORMAL);
    5106      1060283 :   scev_initialize ();
    5107              : 
    5108      1060283 :   calculate_dominance_info (CDI_DOMINATORS);
    5109              : 
    5110              :   /* Calculate the set of non-trapping memory accesses.  */
    5111      1060283 :   nontrap = get_non_trapping ();
    5112              : 
    5113      2001753 :   auto cselim_exec = [&] (basic_block bb, basic_block bb1,
    5114              :                           basic_block bb2, edge e1, edge e2,
    5115              :                           bool diamond_p, gcond *)
    5116              :     {
    5117       941470 :       if (diamond_p)
    5118              :         {
    5119       326728 :           basic_block bb3 = e1->dest;
    5120              : 
    5121              :           /* Only handle sinking of store from 2 bbs only,
    5122              :              The middle bbs don't need to come from the
    5123              :              if always since we are sinking rather than
    5124              :              hoisting. */
    5125       326728 :           if (EDGE_COUNT (bb3->preds) != 2)
    5126              :             return;
    5127       240899 :           if (cond_if_else_store_replacement (bb1, bb2, bb3))
    5128         1017 :             cfgchanged = true;
    5129              :           return;
    5130              :         }
    5131              : 
    5132              :       /* Also make sure that bb1 only have one predecessor and that it
    5133              :          is bb.  */
    5134       614742 :       if (!single_pred_p (bb1)
    5135      1182051 :           || single_pred (bb1) != bb)
    5136              :         return;
    5137              : 
    5138              :       /* bb1 is the middle block, bb2 the join block, bb the split block,
    5139              :          e1 the fallthrough edge from bb1 to bb2.  We can't do the
    5140              :          optimization if the join block has more than two predecessors.  */
    5141       567309 :       if (EDGE_COUNT (bb2->preds) > 2)
    5142              :         return;
    5143              : 
    5144       441946 :       if (cond_store_replacement_limited (bb1, bb2, bb, e1, e2, true))
    5145              :         {
    5146          716 :           cfgchanged = true;
    5147          716 :           return;
    5148              :         }
    5149       441230 :       gimple *assign = cselim_candidate (bb1, bb2, e1);
    5150       441230 :       if (cond_store_replacement (bb1, bb2, e1, e2, assign, nontrap))
    5151         5772 :         cfgchanged = true;
    5152      1060283 :     };
    5153              : 
    5154      1060283 :   execute_over_cond_phis (cselim_exec);
    5155              : 
    5156      2120566 :   delete nontrap;
    5157              :   /* If the CFG has changed, we should cleanup the CFG.  */
    5158      1060283 :   if (cfgchanged)
    5159              :     {
    5160         4403 :       gsi_commit_edge_inserts ();
    5161         4403 :       todo = TODO_cleanup_cfg;
    5162              :     }
    5163      1060283 :   scev_finalize ();
    5164      1060283 :   loop_optimizer_finalize ();
    5165      1060283 :   return todo;
    5166              : }
        

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.