LCOV - code coverage report
Current view: top level - src/compiler - effect-control-linearizer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2027 2280 88.9 %
Date: 2019-04-18 Functions: 163 188 86.7 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/effect-control-linearizer.h"
       6             : 
       7             : #include "src/code-factory.h"
       8             : #include "src/compiler/access-builder.h"
       9             : #include "src/compiler/compiler-source-position-table.h"
      10             : #include "src/compiler/js-graph.h"
      11             : #include "src/compiler/linkage.h"
      12             : #include "src/compiler/node-matchers.h"
      13             : #include "src/compiler/node-origin-table.h"
      14             : #include "src/compiler/node-properties.h"
      15             : #include "src/compiler/node.h"
      16             : #include "src/compiler/schedule.h"
      17             : #include "src/heap/factory-inl.h"
      18             : #include "src/machine-type.h"
      19             : #include "src/objects/heap-number.h"
      20             : #include "src/objects/oddball.h"
      21             : #include "src/objects/ordered-hash-table.h"
      22             : 
      23             : #include "src/ptr-compr-inl.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : namespace compiler {
      28             : 
      29             : namespace {
      30             : bool UsingCompressedPointers() { return false; }
      31             : 
      32             : }  // namespace
      33             : 
      34      463898 : EffectControlLinearizer::EffectControlLinearizer(
      35             :     JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
      36             :     SourcePositionTable* source_positions, NodeOriginTable* node_origins,
      37             :     MaskArrayIndexEnable mask_array_index,
      38             :     std::vector<Handle<Map>>* embedded_maps)
      39             :     : js_graph_(js_graph),
      40             :       schedule_(schedule),
      41             :       temp_zone_(temp_zone),
      42             :       mask_array_index_(mask_array_index),
      43             :       source_positions_(source_positions),
      44             :       node_origins_(node_origins),
      45             :       graph_assembler_(js_graph, nullptr, nullptr, temp_zone),
      46             :       frame_state_zapper_(nullptr),
      47      463898 :       embedded_maps_(embedded_maps) {}
      48             : 
      49      651450 : Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
      50           0 : CommonOperatorBuilder* EffectControlLinearizer::common() const {
      51     1098556 :   return js_graph_->common();
      52             : }
      53           0 : SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
      54           0 :   return js_graph_->simplified();
      55             : }
      56           0 : MachineOperatorBuilder* EffectControlLinearizer::machine() const {
      57      325806 :   return js_graph_->machine();
      58             : }
      59             : 
      60             : namespace {
      61             : 
      62             : struct BlockEffectControlData {
      63             :   Node* current_effect = nullptr;       // New effect.
      64             :   Node* current_control = nullptr;      // New control.
      65             :   Node* current_frame_state = nullptr;  // New frame state.
      66             : };
      67             : 
      68      463899 : class BlockEffectControlMap {
      69             :  public:
      70             :   explicit BlockEffectControlMap(Zone* temp_zone) : map_(temp_zone) {}
      71             : 
      72             :   BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) {
      73    19394726 :     return map_[std::make_pair(from->rpo_number(), to->rpo_number())];
      74             :   }
      75             : 
      76             :   const BlockEffectControlData& For(BasicBlock* from, BasicBlock* to) const {
      77             :     return map_.at(std::make_pair(from->rpo_number(), to->rpo_number()));
      78             :   }
      79             : 
      80             :  private:
      81             :   using Key = std::pair<int32_t, int32_t>;
      82             :   using Map = ZoneMap<Key, BlockEffectControlData>;
      83             : 
      84             :   Map map_;
      85             : };
      86             : 
      87             : // Effect phis that need to be updated after the first pass.
      88             : struct PendingEffectPhi {
      89             :   Node* effect_phi;
      90             :   BasicBlock* block;
      91             : 
      92             :   PendingEffectPhi(Node* effect_phi, BasicBlock* block)
      93       39757 :       : effect_phi(effect_phi), block(block) {}
      94             : };
      95             : 
      96        1038 : void ConnectUnreachableToEnd(Node* effect, Node* control, JSGraph* jsgraph) {
      97             :   Graph* graph = jsgraph->graph();
      98             :   CommonOperatorBuilder* common = jsgraph->common();
      99        1038 :   if (effect->opcode() == IrOpcode::kDead) return;
     100        1038 :   if (effect->opcode() != IrOpcode::kUnreachable) {
     101           0 :     effect = graph->NewNode(common->Unreachable(), effect, control);
     102             :   }
     103        1038 :   Node* throw_node = graph->NewNode(common->Throw(), effect, control);
     104        1038 :   NodeProperties::MergeControlToEnd(graph, common, throw_node);
     105             : }
     106             : 
     107      796433 : void UpdateEffectPhi(Node* node, BasicBlock* block,
     108             :                      BlockEffectControlMap* block_effects, JSGraph* jsgraph) {
     109             :   // Update all inputs to an effect phi with the effects from the given
     110             :   // block->effect map.
     111             :   DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
     112             :   DCHECK_EQ(static_cast<size_t>(node->op()->EffectInputCount()),
     113             :             block->PredecessorCount());
     114     4395525 :   for (int i = 0; i < node->op()->EffectInputCount(); i++) {
     115             :     Node* input = node->InputAt(i);
     116     1799553 :     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
     117             :     const BlockEffectControlData& block_effect =
     118             :         block_effects->For(predecessor, block);
     119     1799555 :     Node* effect = block_effect.current_effect;
     120     1799555 :     if (input != effect) {
     121      132916 :       node->ReplaceInput(i, effect);
     122             :     }
     123             :   }
     124      796426 : }
     125             : 
     126     4382696 : void UpdateBlockControl(BasicBlock* block,
     127             :                         BlockEffectControlMap* block_effects) {
     128             :   Node* control = block->NodeAt(0);
     129             :   DCHECK(NodeProperties::IsControl(control));
     130             : 
     131             :   // Do not rewire the end node.
     132     4382696 :   if (control->opcode() == IrOpcode::kEnd) return;
     133             : 
     134             :   // Update all inputs to the given control node with the correct control.
     135             :   DCHECK(control->opcode() == IrOpcode::kMerge ||
     136             :          static_cast<size_t>(control->op()->ControlInputCount()) ==
     137             :              block->PredecessorCount());
     138     7839594 :   if (static_cast<size_t>(control->op()->ControlInputCount()) !=
     139             :       block->PredecessorCount()) {
     140             :     return;  // We already re-wired the control inputs of this node.
     141             :   }
     142    12383467 :   for (int i = 0; i < control->op()->ControlInputCount(); i++) {
     143     4329998 :     Node* input = NodeProperties::GetControlInput(control, i);
     144     4329947 :     BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
     145             :     const BlockEffectControlData& block_effect =
     146             :         block_effects->For(predecessor, block);
     147     4329956 :     if (input != block_effect.current_control) {
     148             :       NodeProperties::ReplaceControlInput(control, block_effect.current_control,
     149       36648 :                                           i);
     150             :     }
     151             :   }
     152             : }
     153             : 
     154             : bool HasIncomingBackEdges(BasicBlock* block) {
     155    12082237 :   for (BasicBlock* pred : block->predecessors()) {
     156     6993724 :     if (pred->rpo_number() >= block->rpo_number()) {
     157             :       return true;
     158             :     }
     159             :   }
     160             :   return false;
     161             : }
     162             : 
     163      285741 : void RemoveRenameNode(Node* node) {
     164             :   DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
     165             :          IrOpcode::kBeginRegion == node->opcode() ||
     166             :          IrOpcode::kTypeGuard == node->opcode());
     167             :   // Update the value/context uses to the value input of the finish node and
     168             :   // the effect uses to the effect input.
     169     3332479 :   for (Edge edge : node->use_edges()) {
     170             :     DCHECK(!edge.from()->IsDead());
     171     1523369 :     if (NodeProperties::IsEffectEdge(edge)) {
     172      287177 :       edge.UpdateTo(NodeProperties::GetEffectInput(node));
     173             :     } else {
     174             :       DCHECK(!NodeProperties::IsControlEdge(edge));
     175             :       DCHECK(!NodeProperties::IsFrameStateEdge(edge));
     176     1236194 :       edge.UpdateTo(node->InputAt(0));
     177             :     }
     178             :   }
     179      285741 :   node->Kill();
     180      285741 : }
     181             : 
     182     1087354 : void TryCloneBranch(Node* node, BasicBlock* block, Zone* temp_zone,
     183             :                     Graph* graph, CommonOperatorBuilder* common,
     184             :                     BlockEffectControlMap* block_effects,
     185             :                     SourcePositionTable* source_positions,
     186             :                     NodeOriginTable* node_origins) {
     187             :   DCHECK_EQ(IrOpcode::kBranch, node->opcode());
     188             : 
     189             :   // This optimization is a special case of (super)block cloning. It takes an
     190             :   // input graph as shown below and clones the Branch node for every predecessor
     191             :   // to the Merge, essentially removing the Merge completely. This avoids
     192             :   // materializing the bit for the Phi and may offer potential for further
     193             :   // branch folding optimizations (i.e. because one or more inputs to the Phi is
     194             :   // a constant). Note that there may be more Phi nodes hanging off the Merge,
     195             :   // but we can only a certain subset of them currently (actually only Phi and
     196             :   // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
     197             :   // input).
     198             : 
     199             :   //   Control1 ... ControlN
     200             :   //      ^            ^
     201             :   //      |            |   Cond1 ... CondN
     202             :   //      +----+  +----+     ^         ^
     203             :   //           |  |          |         |
     204             :   //           |  |     +----+         |
     205             :   //          Merge<--+ | +------------+
     206             :   //            ^      \|/
     207             :   //            |      Phi
     208             :   //            |       |
     209             :   //          Branch----+
     210             :   //            ^
     211             :   //            |
     212             :   //      +-----+-----+
     213             :   //      |           |
     214             :   //    IfTrue     IfFalse
     215             :   //      ^           ^
     216             :   //      |           |
     217             : 
     218             :   // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
     219             : 
     220             :   // Control1 Cond1 ... ControlN CondN
     221             :   //    ^      ^           ^      ^
     222             :   //    \      /           \      /
     223             :   //     Branch     ...     Branch
     224             :   //       ^                  ^
     225             :   //       |                  |
     226             :   //   +---+---+          +---+----+
     227             :   //   |       |          |        |
     228             :   // IfTrue IfFalse ... IfTrue  IfFalse
     229             :   //   ^       ^          ^        ^
     230             :   //   |       |          |        |
     231             :   //   +--+ +-------------+        |
     232             :   //      | |  +--------------+ +--+
     233             :   //      | |                 | |
     234             :   //     Merge               Merge
     235             :   //       ^                   ^
     236             :   //       |                   |
     237             : 
     238             :   SourcePositionTable::Scope scope(source_positions,
     239     1087354 :                                    source_positions->GetSourcePosition(node));
     240             :   NodeOriginTable::Scope origin_scope(node_origins, "clone branch", node);
     241             :   Node* branch = node;
     242     1087355 :   Node* cond = NodeProperties::GetValueInput(branch, 0);
     243     2150221 :   if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
     244      110508 :   Node* merge = NodeProperties::GetControlInput(branch);
     245      218614 :   if (merge->opcode() != IrOpcode::kMerge ||
     246      108106 :       NodeProperties::GetControlInput(cond) != merge) {
     247             :     return;
     248             :   }
     249             :   // Grab the IfTrue/IfFalse projections of the Branch.
     250      108033 :   BranchMatcher matcher(branch);
     251             :   // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
     252             :   NodeVector phis(temp_zone);
     253      712155 :   for (Node* const use : merge->uses()) {
     254      307013 :     if (use == branch || use == cond) continue;
     255             :     // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
     256             :     // Merge. Ideally, we would just clone the nodes (and everything that
     257             :     // depends on it to some distant join point), but that requires knowledge
     258             :     // about dominance/post-dominance.
     259      115645 :     if (!NodeProperties::IsPhi(use)) return;
     260      107211 :     for (Edge edge : use->use_edges()) {
     261             :       // Right now we can only handle Phi/EffectPhi nodes whose uses are
     262             :       // directly control-dependend on either the IfTrue or the IfFalse
     263             :       // successor, because we know exactly how to update those uses.
     264       11374 :       if (edge.from()->op()->ControlInputCount() != 1) return;
     265       10286 :       Node* control = NodeProperties::GetControlInput(edge.from());
     266       10286 :       if (NodeProperties::IsPhi(edge.from())) {
     267         685 :         control = NodeProperties::GetControlInput(control, edge.index());
     268             :       }
     269       10286 :       if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
     270             :     }
     271       95837 :     phis.push_back(use);
     272             :   }
     273       98129 :   BranchHint const hint = BranchHintOf(branch->op());
     274             :   int const input_count = merge->op()->ControlInputCount();
     275             :   DCHECK_LE(1, input_count);
     276       98129 :   Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
     277             :   Node** const merge_true_inputs = &inputs[0];
     278       98129 :   Node** const merge_false_inputs = &inputs[input_count];
     279      939017 :   for (int index = 0; index < input_count; ++index) {
     280      420444 :     Node* cond1 = NodeProperties::GetValueInput(cond, index);
     281      420444 :     Node* control1 = NodeProperties::GetControlInput(merge, index);
     282      420444 :     Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
     283      840888 :     merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
     284      840888 :     merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
     285             :   }
     286             :   Node* const merge_true = matcher.IfTrue();
     287             :   Node* const merge_false = matcher.IfFalse();
     288       98129 :   merge_true->TrimInputCount(0);
     289       98129 :   merge_false->TrimInputCount(0);
     290      939017 :   for (int i = 0; i < input_count; ++i) {
     291      420444 :     merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
     292      420444 :     merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
     293             :   }
     294             :   DCHECK_EQ(2u, block->SuccessorCount());
     295       98129 :   NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
     296       98129 :   NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
     297             :   int const true_index =
     298       98129 :       block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
     299             :   BlockEffectControlData* true_block_data =
     300       98129 :       &block_effects->For(block, block->SuccessorAt(true_index));
     301             :   BlockEffectControlData* false_block_data =
     302       98129 :       &block_effects->For(block, block->SuccessorAt(true_index ^ 1));
     303      193966 :   for (Node* const phi : phis) {
     304      926919 :     for (int index = 0; index < input_count; ++index) {
     305      831082 :       inputs[index] = phi->InputAt(index);
     306             :     }
     307       95837 :     inputs[input_count] = merge_true;
     308       95837 :     Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
     309       95837 :     inputs[input_count] = merge_false;
     310       95837 :     Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
     311       95837 :     if (phi->UseCount() == 0) {
     312             :       DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
     313             :     } else {
     314       22014 :       for (Edge edge : phi->use_edges()) {
     315        7624 :         Node* control = NodeProperties::GetControlInput(edge.from());
     316        7624 :         if (NodeProperties::IsPhi(edge.from())) {
     317         680 :           control = NodeProperties::GetControlInput(control, edge.index());
     318             :         }
     319             :         DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
     320        7624 :         edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
     321             :       }
     322             :     }
     323       95837 :     if (phi->opcode() == IrOpcode::kEffectPhi) {
     324       95837 :       true_block_data->current_effect = phi_true;
     325       95837 :       false_block_data->current_effect = phi_false;
     326             :     }
     327       95837 :     phi->Kill();
     328             :   }
     329             :   // Fix up IfTrue and IfFalse and kill all dead nodes.
     330       98129 :   if (branch == block->control_input()) {
     331       98129 :     true_block_data->current_control = merge_true;
     332       98129 :     false_block_data->current_control = merge_false;
     333             :   }
     334       98129 :   branch->Kill();
     335       98129 :   cond->Kill();
     336       98129 :   merge->Kill();
     337             : }
     338             : 
     339             : }  // namespace
     340             : 
     341      463892 : void EffectControlLinearizer::Run() {
     342             :   BlockEffectControlMap block_effects(temp_zone());
     343             :   ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
     344             :   ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
     345             :   NodeVector inputs_buffer(temp_zone());
     346             : 
     347     4846593 :   for (BasicBlock* block : *(schedule()->rpo_order())) {
     348             :     size_t instr = 0;
     349             : 
     350             :     // The control node should be the first.
     351     4382698 :     Node* control = block->NodeAt(instr);
     352             :     DCHECK(NodeProperties::IsControl(control));
     353             :     // Update the control inputs.
     354     4382698 :     if (HasIncomingBackEdges(block)) {
     355             :       // If there are back edges, we need to update later because we have not
     356             :       // computed the control yet. This should only happen for loops.
     357             :       DCHECK_EQ(IrOpcode::kLoop, control->opcode());
     358       39757 :       pending_block_controls.push_back(block);
     359             :     } else {
     360             :       // If there are no back edges, we can update now.
     361     4342941 :       UpdateBlockControl(block, &block_effects);
     362             :     }
     363             :     instr++;
     364             : 
     365             :     // Iterate over the phis and update the effect phis.
     366             :     Node* effect_phi = nullptr;
     367             :     Node* terminate = nullptr;
     368    12180018 :     for (; instr < block->NodeCount(); instr++) {
     369             :       Node* node = block->NodeAt(instr);
     370             :       // Only go through the phis and effect phis.
     371     3848572 :       if (node->opcode() == IrOpcode::kEffectPhi) {
     372             :         // There should be at most one effect phi in a block.
     373             :         DCHECK_NULL(effect_phi);
     374             :         // IfException blocks should not have effect phis.
     375             :         DCHECK_NE(IrOpcode::kIfException, control->opcode());
     376             :         effect_phi = node;
     377     3063256 :       } else if (node->opcode() == IrOpcode::kPhi) {
     378             :         // Just skip phis.
     379     2750108 :       } else if (node->opcode() == IrOpcode::kTerminate) {
     380             :         DCHECK_NULL(terminate);
     381             :         terminate = node;
     382             :       } else {
     383             :         break;
     384             :       }
     385             :     }
     386             : 
     387     4382673 :     if (effect_phi) {
     388             :       // Make sure we update the inputs to the incoming blocks' effects.
     389      785331 :       if (HasIncomingBackEdges(block)) {
     390             :         // In case of loops, we do not update the effect phi immediately
     391             :         // because the back predecessor has not been handled yet. We just
     392             :         // record the effect phi for later processing.
     393       39750 :         pending_effect_phis.push_back(PendingEffectPhi(effect_phi, block));
     394             :       } else {
     395      745581 :         UpdateEffectPhi(effect_phi, block, &block_effects, jsgraph());
     396             :       }
     397             :     }
     398             : 
     399     4382713 :     Node* effect = effect_phi;
     400     4382713 :     if (effect == nullptr) {
     401             :       // There was no effect phi.
     402     3597354 :       if (block == schedule()->start()) {
     403             :         // Start block => effect is start.
     404             :         DCHECK_EQ(graph()->start(), control);
     405      463894 :         effect = graph()->start();
     406     6266920 :       } else if (control->opcode() == IrOpcode::kEnd) {
     407             :         // End block is just a dummy, no effect needed.
     408             :         DCHECK_EQ(BasicBlock::kNone, block->control());
     409             :         DCHECK_EQ(1u, block->size());
     410      462892 :         effect = nullptr;
     411             :       } else {
     412             :         // If all the predecessors have the same effect, we can use it as our
     413             :         // current effect.
     414    13555235 :         for (size_t i = 0; i < block->PredecessorCount(); ++i) {
     415             :           const BlockEffectControlData& data =
     416             :               block_effects.For(block->PredecessorAt(i), block);
     417     2749124 :           if (!effect) effect = data.current_effect;
     418     2749124 :           if (data.current_effect != effect) {
     419       11091 :             effect = nullptr;
     420       11091 :             break;
     421             :           }
     422             :         }
     423     2670574 :         if (effect == nullptr) {
     424             :           DCHECK_NE(IrOpcode::kIfException, control->opcode());
     425             :           // The input blocks do not have the same effect. We have
     426             :           // to create an effect phi node.
     427             :           inputs_buffer.clear();
     428       22182 :           inputs_buffer.resize(block->PredecessorCount(), jsgraph()->Dead());
     429       11091 :           inputs_buffer.push_back(control);
     430       44364 :           effect = graph()->NewNode(
     431       11091 :               common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
     432       11091 :               static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
     433             :           // For loops, we update the effect phi node later to break cycles.
     434       22182 :           if (control->opcode() == IrOpcode::kLoop) {
     435          14 :             pending_effect_phis.push_back(PendingEffectPhi(effect, block));
     436             :           } else {
     437       11084 :             UpdateEffectPhi(effect, block, &block_effects, jsgraph());
     438             :           }
     439     5318966 :         } else if (control->opcode() == IrOpcode::kIfException) {
     440             :           // The IfException is connected into the effect chain, so we need
     441             :           // to update the effect here.
     442      200861 :           NodeProperties::ReplaceEffectInput(control, effect);
     443      200861 :           effect = control;
     444             :         }
     445             :       }
     446             :     }
     447             : 
     448             :     // Fixup the Terminate node.
     449     4382719 :     if (terminate != nullptr) {
     450       39756 :       NodeProperties::ReplaceEffectInput(terminate, effect);
     451             :     }
     452             : 
     453             :     // The frame state at block entry is determined by the frame states leaving
     454             :     // all predecessors. In case there is no frame state dominating this block,
     455             :     // we can rely on a checkpoint being present before the next deoptimization.
     456             :     // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
     457             :     // once deoptimizing nodes roam freely through the schedule.
     458     4382719 :     Node* frame_state = nullptr;
     459     4382719 :     if (block != schedule()->start()) {
     460             :       // If all the predecessors have the same effect, we can use it
     461             :       // as our current effect.
     462             :       frame_state =
     463     3918798 :           block_effects.For(block->PredecessorAt(0), block).current_frame_state;
     464    11106807 :       for (size_t i = 1; i < block->PredecessorCount(); i++) {
     465     1181048 :         if (block_effects.For(block->PredecessorAt(i), block)
     466     1181048 :                 .current_frame_state != frame_state) {
     467       91311 :           frame_state = nullptr;
     468       91311 :           frame_state_zapper_ = graph()->end();
     469       91311 :           break;
     470             :         }
     471             :       }
     472             :     }
     473             : 
     474             :     // Process the ordinary instructions.
     475   109836257 :     for (; instr < block->NodeCount(); instr++) {
     476             :       Node* node = block->NodeAt(instr);
     477    33690335 :       ProcessNode(node, &frame_state, &effect, &control);
     478             :     }
     479             : 
     480     4382658 :     switch (block->control()) {
     481             :       case BasicBlock::kGoto:
     482             :       case BasicBlock::kNone:
     483             :         break;
     484             : 
     485             :       case BasicBlock::kCall:
     486             :       case BasicBlock::kTailCall:
     487             :       case BasicBlock::kSwitch:
     488             :       case BasicBlock::kReturn:
     489             :       case BasicBlock::kDeoptimize:
     490             :       case BasicBlock::kThrow:
     491      899897 :         ProcessNode(block->control_input(), &frame_state, &effect, &control);
     492      899896 :         break;
     493             : 
     494             :       case BasicBlock::kBranch:
     495     1087346 :         ProcessNode(block->control_input(), &frame_state, &effect, &control);
     496     2174712 :         TryCloneBranch(block->control_input(), block, temp_zone(), graph(),
     497             :                        common(), &block_effects, source_positions_,
     498     1087356 :                        node_origins_);
     499     1087356 :         break;
     500             :     }
     501             : 
     502             :     // Store the effect, control and frame state for later use.
     503    13985375 :     for (BasicBlock* successor : block->successors()) {
     504     5220007 :       BlockEffectControlData* data = &block_effects.For(block, successor);
     505     5220041 :       if (data->current_effect == nullptr) {
     506     5028356 :         data->current_effect = effect;
     507             :       }
     508     5220041 :       if (data->current_control == nullptr) {
     509     5023783 :         data->current_control = control;
     510             :       }
     511     5220041 :       data->current_frame_state = frame_state;
     512             :     }
     513             :   }
     514             : 
     515      503652 :   for (BasicBlock* pending_block_control : pending_block_controls) {
     516       39756 :     UpdateBlockControl(pending_block_control, &block_effects);
     517             :   }
     518             :   // Update the incoming edges of the effect phis that could not be processed
     519             :   // during the first pass (because they could have incoming back edges).
     520      503653 :   for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
     521       39757 :     UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
     522       39757 :                     &block_effects, jsgraph());
     523             :   }
     524      463899 : }
     525             : 
     526    35677492 : void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
     527             :                                           Node** effect, Node** control) {
     528             :   SourcePositionTable::Scope scope(source_positions_,
     529    35677492 :                                    source_positions_->GetSourcePosition(node));
     530    35677464 :   NodeOriginTable::Scope origin_scope(node_origins_, "process node", node);
     531             : 
     532             :   // If the node needs to be wired into the effect/control chain, do this
     533             :   // here. Pass current frame state for lowering to eager deoptimization.
     534    35677464 :   if (TryWireInStateEffect(node, *frame_state, effect, control)) {
     535             :     return;
     536             :   }
     537             : 
     538             :   // If the node has a visible effect, then there must be a checkpoint in the
     539             :   // effect chain before we are allowed to place another eager deoptimization
     540             :   // point. We zap the frame state to ensure this invariant is maintained.
     541    67487738 :   if (region_observability_ == RegionObservability::kObservable &&
     542             :       !node->op()->HasProperty(Operator::kNoWrite)) {
     543     3650998 :     *frame_state = nullptr;
     544     3650998 :     frame_state_zapper_ = node;
     545             :   }
     546             : 
     547             :   // Remove the end markers of 'atomic' allocation region because the
     548             :   // region should be wired-in now.
     549    34570631 :   if (node->opcode() == IrOpcode::kFinishRegion) {
     550             :     // Reset the current region observability.
     551      132706 :     region_observability_ = RegionObservability::kObservable;
     552             :     // Update the value uses to the value input of the finish node and
     553             :     // the effect uses to the effect input.
     554      132706 :     return RemoveRenameNode(node);
     555             :   }
     556    34437925 :   if (node->opcode() == IrOpcode::kBeginRegion) {
     557             :     // Determine the observability for this region and use that for all
     558             :     // nodes inside the region (i.e. ignore the absence of kNoWrite on
     559             :     // StoreField and other operators).
     560             :     DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
     561      132706 :     region_observability_ = RegionObservabilityOf(node->op());
     562             :     // Update the value uses to the value input of the finish node and
     563             :     // the effect uses to the effect input.
     564      132706 :     return RemoveRenameNode(node);
     565             :   }
     566    34305219 :   if (node->opcode() == IrOpcode::kTypeGuard) {
     567       20329 :     return RemoveRenameNode(node);
     568             :   }
     569             : 
     570             :   // Special treatment for checkpoint nodes.
     571    34284890 :   if (node->opcode() == IrOpcode::kCheckpoint) {
     572             :     // Unlink the check point; effect uses will be updated to the incoming
     573             :     // effect that is passed. The frame state is preserved for lowering.
     574             :     DCHECK_EQ(RegionObservability::kObservable, region_observability_);
     575     2751524 :     *frame_state = NodeProperties::GetFrameStateInput(node);
     576     2751523 :     return;
     577             :   }
     578             : 
     579             :   // The IfSuccess nodes should always start a basic block (and basic block
     580             :   // start nodes are not handled in the ProcessNode method).
     581             :   DCHECK_NE(IrOpcode::kIfSuccess, node->opcode());
     582             : 
     583             :   // If the node takes an effect, replace with the current one.
     584    31533366 :   if (node->op()->EffectInputCount() > 0) {
     585             :     DCHECK_EQ(1, node->op()->EffectInputCount());
     586     8135403 :     Node* input_effect = NodeProperties::GetEffectInput(node);
     587             : 
     588     8135397 :     if (input_effect != *effect) {
     589     2758529 :       NodeProperties::ReplaceEffectInput(node, *effect);
     590             :     }
     591             : 
     592             :     // If the node produces an effect, update our current effect. (However,
     593             :     // ignore new effect chains started with ValueEffect.)
     594     8135371 :     if (node->op()->EffectOutputCount() > 0) {
     595             :       DCHECK_EQ(1, node->op()->EffectOutputCount());
     596     7441609 :       *effect = node;
     597             :     }
     598             :   } else {
     599             :     // New effect chain is only started with a Start or ValueEffect node.
     600             :     DCHECK(node->op()->EffectOutputCount() == 0 ||
     601             :            node->opcode() == IrOpcode::kStart);
     602             :   }
     603             : 
     604             :   // Rewire control inputs.
     605    48996756 :   for (int i = 0; i < node->op()->ControlInputCount(); i++) {
     606     8731708 :     NodeProperties::ReplaceControlInput(node, *control, i);
     607             :   }
     608             :   // Update the current control.
     609    31533337 :   if (node->op()->ControlOutputCount() > 0) {
     610     4760812 :     *control = node;
     611             :   }
     612             : 
     613             :   // Break the effect chain on {Unreachable} and reconnect to the graph end.
     614             :   // Mark the following code for deletion by connecting to the {Dead} node.
     615    31533337 :   if (node->opcode() == IrOpcode::kUnreachable) {
     616        1038 :     ConnectUnreachableToEnd(*effect, *control, jsgraph());
     617        1038 :     *effect = *control = jsgraph()->Dead();
     618             :   }
     619             : }
     620             : 
     621    35677489 : bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
     622             :                                                    Node* frame_state,
     623             :                                                    Node** effect,
     624             :                                                    Node** control) {
     625    71354978 :   gasm()->Reset(*effect, *control);
     626             :   Node* result = nullptr;
     627    35677502 :   switch (node->opcode()) {
     628             :     case IrOpcode::kChangeBitToTagged:
     629        9669 :       result = LowerChangeBitToTagged(node);
     630        9669 :       break;
     631             :     case IrOpcode::kChangeInt31ToTaggedSigned:
     632       39142 :       result = LowerChangeInt31ToTaggedSigned(node);
     633       39142 :       break;
     634             :     case IrOpcode::kChangeInt32ToTagged:
     635       35958 :       result = LowerChangeInt32ToTagged(node);
     636       35958 :       break;
     637             :     case IrOpcode::kChangeInt64ToTagged:
     638          45 :       result = LowerChangeInt64ToTagged(node);
     639          45 :       break;
     640             :     case IrOpcode::kChangeUint32ToTagged:
     641         639 :       result = LowerChangeUint32ToTagged(node);
     642         639 :       break;
     643             :     case IrOpcode::kChangeUint64ToTagged:
     644          53 :       result = LowerChangeUint64ToTagged(node);
     645          53 :       break;
     646             :     case IrOpcode::kChangeFloat64ToTagged:
     647       53379 :       result = LowerChangeFloat64ToTagged(node);
     648       53378 :       break;
     649             :     case IrOpcode::kChangeFloat64ToTaggedPointer:
     650          91 :       result = LowerChangeFloat64ToTaggedPointer(node);
     651          91 :       break;
     652             :     case IrOpcode::kChangeTaggedSignedToInt32:
     653       49796 :       result = LowerChangeTaggedSignedToInt32(node);
     654       49796 :       break;
     655             :     case IrOpcode::kChangeTaggedSignedToInt64:
     656         283 :       result = LowerChangeTaggedSignedToInt64(node);
     657         283 :       break;
     658             :     case IrOpcode::kChangeTaggedToBit:
     659      139282 :       result = LowerChangeTaggedToBit(node);
     660      139282 :       break;
     661             :     case IrOpcode::kChangeTaggedToInt32:
     662        1756 :       result = LowerChangeTaggedToInt32(node);
     663        1756 :       break;
     664             :     case IrOpcode::kChangeTaggedToUint32:
     665         394 :       result = LowerChangeTaggedToUint32(node);
     666         394 :       break;
     667             :     case IrOpcode::kChangeTaggedToInt64:
     668           2 :       result = LowerChangeTaggedToInt64(node);
     669           2 :       break;
     670             :     case IrOpcode::kChangeTaggedToFloat64:
     671             :       result = LowerChangeTaggedToFloat64(node);
     672       11269 :       break;
     673             :     case IrOpcode::kChangeTaggedToTaggedSigned:
     674          14 :       result = LowerChangeTaggedToTaggedSigned(node);
     675          14 :       break;
     676             :     case IrOpcode::kChangeCompressedToTaggedSigned:
     677           0 :       result = LowerChangeCompressedToTaggedSigned(node);
     678           0 :       break;
     679             :     case IrOpcode::kChangeTaggedToCompressedSigned:
     680           0 :       result = LowerChangeTaggedToCompressedSigned(node);
     681           0 :       break;
     682             :     case IrOpcode::kTruncateTaggedToBit:
     683       47616 :       result = LowerTruncateTaggedToBit(node);
     684       47616 :       break;
     685             :     case IrOpcode::kTruncateTaggedPointerToBit:
     686         394 :       result = LowerTruncateTaggedPointerToBit(node);
     687         394 :       break;
     688             :     case IrOpcode::kTruncateTaggedToFloat64:
     689         727 :       result = LowerTruncateTaggedToFloat64(node);
     690         727 :       break;
     691             :     case IrOpcode::kPoisonIndex:
     692        1024 :       result = LowerPoisonIndex(node);
     693        1024 :       break;
     694             :     case IrOpcode::kCheckMaps:
     695       51347 :       LowerCheckMaps(node, frame_state);
     696       51347 :       break;
     697             :     case IrOpcode::kCompareMaps:
     698        7413 :       result = LowerCompareMaps(node);
     699        7413 :       break;
     700             :     case IrOpcode::kCheckNumber:
     701         474 :       result = LowerCheckNumber(node, frame_state);
     702         474 :       break;
     703             :     case IrOpcode::kCheckReceiver:
     704         809 :       result = LowerCheckReceiver(node, frame_state);
     705         809 :       break;
     706             :     case IrOpcode::kCheckReceiverOrNullOrUndefined:
     707          72 :       result = LowerCheckReceiverOrNullOrUndefined(node, frame_state);
     708          72 :       break;
     709             :     case IrOpcode::kCheckSymbol:
     710          32 :       result = LowerCheckSymbol(node, frame_state);
     711          32 :       break;
     712             :     case IrOpcode::kCheckString:
     713        6287 :       result = LowerCheckString(node, frame_state);
     714        6287 :       break;
     715             :     case IrOpcode::kCheckInternalizedString:
     716        1395 :       result = LowerCheckInternalizedString(node, frame_state);
     717        1395 :       break;
     718             :     case IrOpcode::kCheckIf:
     719       14522 :       LowerCheckIf(node, frame_state);
     720       14522 :       break;
     721             :     case IrOpcode::kCheckedInt32Add:
     722       55848 :       result = LowerCheckedInt32Add(node, frame_state);
     723       55849 :       break;
     724             :     case IrOpcode::kCheckedInt32Sub:
     725        7611 :       result = LowerCheckedInt32Sub(node, frame_state);
     726        7611 :       break;
     727             :     case IrOpcode::kCheckedInt32Div:
     728         243 :       result = LowerCheckedInt32Div(node, frame_state);
     729         243 :       break;
     730             :     case IrOpcode::kCheckedInt32Mod:
     731         822 :       result = LowerCheckedInt32Mod(node, frame_state);
     732         822 :       break;
     733             :     case IrOpcode::kCheckedUint32Div:
     734          52 :       result = LowerCheckedUint32Div(node, frame_state);
     735          52 :       break;
     736             :     case IrOpcode::kCheckedUint32Mod:
     737          37 :       result = LowerCheckedUint32Mod(node, frame_state);
     738          37 :       break;
     739             :     case IrOpcode::kCheckedInt32Mul:
     740        5819 :       result = LowerCheckedInt32Mul(node, frame_state);
     741        5819 :       break;
     742             :     case IrOpcode::kCheckedInt32ToTaggedSigned:
     743           0 :       result = LowerCheckedInt32ToTaggedSigned(node, frame_state);
     744           0 :       break;
     745             :     case IrOpcode::kCheckedInt64ToInt32:
     746           9 :       result = LowerCheckedInt64ToInt32(node, frame_state);
     747           9 :       break;
     748             :     case IrOpcode::kCheckedInt64ToTaggedSigned:
     749         151 :       result = LowerCheckedInt64ToTaggedSigned(node, frame_state);
     750         151 :       break;
     751             :     case IrOpcode::kCheckedUint32Bounds:
     752       52521 :       result = LowerCheckedUint32Bounds(node, frame_state);
     753       52521 :       break;
     754             :     case IrOpcode::kCheckedUint32ToInt32:
     755         386 :       result = LowerCheckedUint32ToInt32(node, frame_state);
     756         386 :       break;
     757             :     case IrOpcode::kCheckedUint32ToTaggedSigned:
     758           7 :       result = LowerCheckedUint32ToTaggedSigned(node, frame_state);
     759           7 :       break;
     760             :     case IrOpcode::kCheckedUint64Bounds:
     761         195 :       result = LowerCheckedUint64Bounds(node, frame_state);
     762         195 :       break;
     763             :     case IrOpcode::kCheckedUint64ToInt32:
     764           0 :       result = LowerCheckedUint64ToInt32(node, frame_state);
     765           0 :       break;
     766             :     case IrOpcode::kCheckedUint64ToTaggedSigned:
     767           0 :       result = LowerCheckedUint64ToTaggedSigned(node, frame_state);
     768           0 :       break;
     769             :     case IrOpcode::kCheckedFloat64ToInt32:
     770        2315 :       result = LowerCheckedFloat64ToInt32(node, frame_state);
     771        2315 :       break;
     772             :     case IrOpcode::kCheckedFloat64ToInt64:
     773          16 :       result = LowerCheckedFloat64ToInt64(node, frame_state);
     774          16 :       break;
     775             :     case IrOpcode::kCheckedTaggedSignedToInt32:
     776       24759 :       if (frame_state == nullptr) {
     777           0 :         FATAL("No frame state (zapped by #%d: %s)", frame_state_zapper_->id(),
     778           0 :               frame_state_zapper_->op()->mnemonic());
     779             :       }
     780       24759 :       result = LowerCheckedTaggedSignedToInt32(node, frame_state);
     781       24759 :       break;
     782             :     case IrOpcode::kCheckedTaggedToInt32:
     783        2312 :       result = LowerCheckedTaggedToInt32(node, frame_state);
     784        2312 :       break;
     785             :     case IrOpcode::kCheckedTaggedToInt64:
     786          87 :       result = LowerCheckedTaggedToInt64(node, frame_state);
     787          87 :       break;
     788             :     case IrOpcode::kCheckedTaggedToFloat64:
     789       51131 :       result = LowerCheckedTaggedToFloat64(node, frame_state);
     790       51131 :       break;
     791             :     case IrOpcode::kCheckedTaggedToTaggedSigned:
     792       18852 :       result = LowerCheckedTaggedToTaggedSigned(node, frame_state);
     793       18852 :       break;
     794             :     case IrOpcode::kCheckedTaggedToTaggedPointer:
     795       34469 :       result = LowerCheckedTaggedToTaggedPointer(node, frame_state);
     796       34469 :       break;
     797             :     case IrOpcode::kCheckedCompressedToTaggedSigned:
     798           0 :       result = LowerCheckedCompressedToTaggedSigned(node, frame_state);
     799           0 :       break;
     800             :     case IrOpcode::kCheckedCompressedToTaggedPointer:
     801           0 :       result = LowerCheckedCompressedToTaggedPointer(node, frame_state);
     802           0 :       break;
     803             :     case IrOpcode::kCheckedTaggedToCompressedSigned:
     804           0 :       result = LowerCheckedTaggedToCompressedSigned(node, frame_state);
     805           0 :       break;
     806             :     case IrOpcode::kCheckedTaggedToCompressedPointer:
     807           0 :       result = LowerCheckedTaggedToCompressedPointer(node, frame_state);
     808           0 :       break;
     809             :     case IrOpcode::kTruncateTaggedToWord32:
     810         501 :       result = LowerTruncateTaggedToWord32(node);
     811         501 :       break;
     812             :     case IrOpcode::kCheckedTruncateTaggedToWord32:
     813        1177 :       result = LowerCheckedTruncateTaggedToWord32(node, frame_state);
     814        1177 :       break;
     815             :     case IrOpcode::kNumberToString:
     816         993 :       result = LowerNumberToString(node);
     817         993 :       break;
     818             :     case IrOpcode::kObjectIsArrayBufferView:
     819          16 :       result = LowerObjectIsArrayBufferView(node);
     820          16 :       break;
     821             :     case IrOpcode::kObjectIsBigInt:
     822          25 :       result = LowerObjectIsBigInt(node);
     823          25 :       break;
     824             :     case IrOpcode::kObjectIsCallable:
     825         104 :       result = LowerObjectIsCallable(node);
     826         104 :       break;
     827             :     case IrOpcode::kObjectIsConstructor:
     828         379 :       result = LowerObjectIsConstructor(node);
     829         379 :       break;
     830             :     case IrOpcode::kObjectIsDetectableCallable:
     831       14119 :       result = LowerObjectIsDetectableCallable(node);
     832       14119 :       break;
     833             :     case IrOpcode::kObjectIsMinusZero:
     834          23 :       result = LowerObjectIsMinusZero(node);
     835          23 :       break;
     836             :     case IrOpcode::kNumberIsMinusZero:
     837          98 :       result = LowerNumberIsMinusZero(node);
     838          98 :       break;
     839             :     case IrOpcode::kObjectIsNaN:
     840         716 :       result = LowerObjectIsNaN(node);
     841         716 :       break;
     842             :     case IrOpcode::kNumberIsNaN:
     843        2516 :       result = LowerNumberIsNaN(node);
     844        2516 :       break;
     845             :     case IrOpcode::kObjectIsNonCallable:
     846        6060 :       result = LowerObjectIsNonCallable(node);
     847        6060 :       break;
     848             :     case IrOpcode::kObjectIsNumber:
     849        7582 :       result = LowerObjectIsNumber(node);
     850        7582 :       break;
     851             :     case IrOpcode::kObjectIsReceiver:
     852       19606 :       result = LowerObjectIsReceiver(node);
     853       19606 :       break;
     854             :     case IrOpcode::kObjectIsSmi:
     855        4130 :       result = LowerObjectIsSmi(node);
     856        4130 :       break;
     857             :     case IrOpcode::kObjectIsString:
     858        2223 :       result = LowerObjectIsString(node);
     859        2223 :       break;
     860             :     case IrOpcode::kObjectIsSymbol:
     861          23 :       result = LowerObjectIsSymbol(node);
     862          23 :       break;
     863             :     case IrOpcode::kObjectIsUndetectable:
     864        1425 :       result = LowerObjectIsUndetectable(node);
     865        1425 :       break;
     866             :     case IrOpcode::kArgumentsFrame:
     867       16914 :       result = LowerArgumentsFrame(node);
     868       16914 :       break;
     869             :     case IrOpcode::kArgumentsLength:
     870       16941 :       result = LowerArgumentsLength(node);
     871       16941 :       break;
     872             :     case IrOpcode::kToBoolean:
     873         200 :       result = LowerToBoolean(node);
     874         200 :       break;
     875             :     case IrOpcode::kTypeOf:
     876       21373 :       result = LowerTypeOf(node);
     877       21373 :       break;
     878             :     case IrOpcode::kNewDoubleElements:
     879          28 :       result = LowerNewDoubleElements(node);
     880          28 :       break;
     881             :     case IrOpcode::kNewSmiOrObjectElements:
     882         476 :       result = LowerNewSmiOrObjectElements(node);
     883         476 :       break;
     884             :     case IrOpcode::kNewArgumentsElements:
     885       16437 :       result = LowerNewArgumentsElements(node);
     886       16437 :       break;
     887             :     case IrOpcode::kNewConsString:
     888        5193 :       result = LowerNewConsString(node);
     889        5193 :       break;
     890             :     case IrOpcode::kSameValue:
     891           1 :       result = LowerSameValue(node);
     892           1 :       break;
     893             :     case IrOpcode::kSameValueNumbersOnly:
     894         162 :       result = LowerSameValueNumbersOnly(node);
     895         162 :       break;
     896             :     case IrOpcode::kNumberSameValue:
     897          77 :       result = LowerNumberSameValue(node);
     898          77 :       break;
     899             :     case IrOpcode::kDeadValue:
     900        1303 :       result = LowerDeadValue(node);
     901        1303 :       break;
     902             :     case IrOpcode::kStringConcat:
     903       20902 :       result = LowerStringConcat(node);
     904       20902 :       break;
     905             :     case IrOpcode::kStringFromSingleCharCode:
     906         946 :       result = LowerStringFromSingleCharCode(node);
     907         946 :       break;
     908             :     case IrOpcode::kStringFromSingleCodePoint:
     909         207 :       result = LowerStringFromSingleCodePoint(node);
     910         207 :       break;
     911             :     case IrOpcode::kStringIndexOf:
     912         268 :       result = LowerStringIndexOf(node);
     913         268 :       break;
     914             :     case IrOpcode::kStringLength:
     915       24595 :       result = LowerStringLength(node);
     916       24595 :       break;
     917             :     case IrOpcode::kStringToNumber:
     918         330 :       result = LowerStringToNumber(node);
     919         330 :       break;
     920             :     case IrOpcode::kStringCharCodeAt:
     921        2236 :       result = LowerStringCharCodeAt(node);
     922        2236 :       break;
     923             :     case IrOpcode::kStringCodePointAt:
     924         223 :       result = LowerStringCodePointAt(node, UnicodeEncodingOf(node->op()));
     925         223 :       break;
     926             :     case IrOpcode::kStringToLowerCaseIntl:
     927          96 :       result = LowerStringToLowerCaseIntl(node);
     928          96 :       break;
     929             :     case IrOpcode::kStringToUpperCaseIntl:
     930          36 :       result = LowerStringToUpperCaseIntl(node);
     931          36 :       break;
     932             :     case IrOpcode::kStringSubstring:
     933        1080 :       result = LowerStringSubstring(node);
     934        1080 :       break;
     935             :     case IrOpcode::kStringEqual:
     936       10299 :       result = LowerStringEqual(node);
     937       10299 :       break;
     938             :     case IrOpcode::kStringLessThan:
     939         121 :       result = LowerStringLessThan(node);
     940         121 :       break;
     941             :     case IrOpcode::kStringLessThanOrEqual:
     942         699 :       result = LowerStringLessThanOrEqual(node);
     943         699 :       break;
     944             :     case IrOpcode::kNumberIsFloat64Hole:
     945          61 :       result = LowerNumberIsFloat64Hole(node);
     946          61 :       break;
     947             :     case IrOpcode::kNumberIsFinite:
     948         126 :       result = LowerNumberIsFinite(node);
     949         126 :       break;
     950             :     case IrOpcode::kObjectIsFiniteNumber:
     951           7 :       result = LowerObjectIsFiniteNumber(node);
     952           7 :       break;
     953             :     case IrOpcode::kNumberIsInteger:
     954         119 :       result = LowerNumberIsInteger(node);
     955         119 :       break;
     956             :     case IrOpcode::kObjectIsInteger:
     957           7 :       result = LowerObjectIsInteger(node);
     958           7 :       break;
     959             :     case IrOpcode::kNumberIsSafeInteger:
     960           7 :       result = LowerNumberIsSafeInteger(node);
     961           7 :       break;
     962             :     case IrOpcode::kObjectIsSafeInteger:
     963           7 :       result = LowerObjectIsSafeInteger(node);
     964           7 :       break;
     965             :     case IrOpcode::kCheckFloat64Hole:
     966         470 :       result = LowerCheckFloat64Hole(node, frame_state);
     967         470 :       break;
     968             :     case IrOpcode::kCheckNotTaggedHole:
     969         102 :       result = LowerCheckNotTaggedHole(node, frame_state);
     970         102 :       break;
     971             :     case IrOpcode::kConvertTaggedHoleToUndefined:
     972        1668 :       result = LowerConvertTaggedHoleToUndefined(node);
     973        1668 :       break;
     974             :     case IrOpcode::kCheckEqualsInternalizedString:
     975         109 :       LowerCheckEqualsInternalizedString(node, frame_state);
     976         109 :       break;
     977             :     case IrOpcode::kAllocate:
     978      112778 :       result = LowerAllocate(node);
     979      112778 :       break;
     980             :     case IrOpcode::kCheckEqualsSymbol:
     981          18 :       LowerCheckEqualsSymbol(node, frame_state);
     982          18 :       break;
     983             :     case IrOpcode::kPlainPrimitiveToNumber:
     984          20 :       result = LowerPlainPrimitiveToNumber(node);
     985          20 :       break;
     986             :     case IrOpcode::kPlainPrimitiveToWord32:
     987           9 :       result = LowerPlainPrimitiveToWord32(node);
     988           9 :       break;
     989             :     case IrOpcode::kPlainPrimitiveToFloat64:
     990           0 :       result = LowerPlainPrimitiveToFloat64(node);
     991           0 :       break;
     992             :     case IrOpcode::kEnsureWritableFastElements:
     993        1683 :       result = LowerEnsureWritableFastElements(node);
     994        1683 :       break;
     995             :     case IrOpcode::kMaybeGrowFastElements:
     996        3516 :       result = LowerMaybeGrowFastElements(node, frame_state);
     997        3516 :       break;
     998             :     case IrOpcode::kTransitionElementsKind:
     999         630 :       LowerTransitionElementsKind(node);
    1000         630 :       break;
    1001             :     case IrOpcode::kLoadMessage:
    1002        7217 :       result = LowerLoadMessage(node);
    1003        7217 :       break;
    1004             :     case IrOpcode::kStoreMessage:
    1005       29703 :       LowerStoreMessage(node);
    1006       29703 :       break;
    1007             :     case IrOpcode::kLoadFieldByIndex:
    1008         582 :       result = LowerLoadFieldByIndex(node);
    1009         582 :       break;
    1010             :     case IrOpcode::kLoadTypedElement:
    1011        4601 :       result = LowerLoadTypedElement(node);
    1012        4601 :       break;
    1013             :     case IrOpcode::kLoadDataViewElement:
    1014         268 :       result = LowerLoadDataViewElement(node);
    1015         268 :       break;
    1016             :     case IrOpcode::kLoadStackArgument:
    1017         572 :       result = LowerLoadStackArgument(node);
    1018         572 :       break;
    1019             :     case IrOpcode::kStoreTypedElement:
    1020        4369 :       LowerStoreTypedElement(node);
    1021        4369 :       break;
    1022             :     case IrOpcode::kStoreDataViewElement:
    1023         196 :       LowerStoreDataViewElement(node);
    1024         196 :       break;
    1025             :     case IrOpcode::kStoreSignedSmallElement:
    1026          70 :       LowerStoreSignedSmallElement(node);
    1027          70 :       break;
    1028             :     case IrOpcode::kFindOrderedHashMapEntry:
    1029         162 :       result = LowerFindOrderedHashMapEntry(node);
    1030         162 :       break;
    1031             :     case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
    1032          16 :       result = LowerFindOrderedHashMapEntryForInt32Key(node);
    1033          16 :       break;
    1034             :     case IrOpcode::kTransitionAndStoreNumberElement:
    1035          28 :       LowerTransitionAndStoreNumberElement(node);
    1036          28 :       break;
    1037             :     case IrOpcode::kTransitionAndStoreNonNumberElement:
    1038          25 :       LowerTransitionAndStoreNonNumberElement(node);
    1039          25 :       break;
    1040             :     case IrOpcode::kTransitionAndStoreElement:
    1041          86 :       LowerTransitionAndStoreElement(node);
    1042          86 :       break;
    1043             :     case IrOpcode::kRuntimeAbort:
    1044        2468 :       LowerRuntimeAbort(node);
    1045        2468 :       break;
    1046             :     case IrOpcode::kConvertReceiver:
    1047         873 :       result = LowerConvertReceiver(node);
    1048         873 :       break;
    1049             :     case IrOpcode::kFloat64RoundUp:
    1050       16460 :       if (!LowerFloat64RoundUp(node).To(&result)) {
    1051             :         return false;
    1052             :       }
    1053             :       break;
    1054             :     case IrOpcode::kFloat64RoundDown:
    1055       53588 :       if (!LowerFloat64RoundDown(node).To(&result)) {
    1056             :         return false;
    1057             :       }
    1058             :       break;
    1059             :     case IrOpcode::kFloat64RoundTruncate:
    1060       13828 :       if (!LowerFloat64RoundTruncate(node).To(&result)) {
    1061             :         return false;
    1062             :       }
    1063             :       break;
    1064             :     case IrOpcode::kFloat64RoundTiesEven:
    1065         532 :       if (!LowerFloat64RoundTiesEven(node).To(&result)) {
    1066             :         return false;
    1067             :       }
    1068             :       break;
    1069             :     case IrOpcode::kDateNow:
    1070          13 :       result = LowerDateNow(node);
    1071          13 :       break;
    1072             :     default:
    1073             :       return false;
    1074             :   }
    1075             : 
    1076     2213936 :   if ((result ? 1 : 0) != node->op()->ValueOutputCount()) {
    1077             :     FATAL(
    1078             :         "Effect control linearizer lowering of '%s':"
    1079             :         " value output count does not agree.",
    1080           0 :         node->op()->mnemonic());
    1081             :   }
    1082             : 
    1083     1106968 :   *effect = gasm()->ExtractCurrentEffect();
    1084     1106970 :   *control = gasm()->ExtractCurrentControl();
    1085     1106972 :   NodeProperties::ReplaceUses(node, result, *effect, *control);
    1086     1106973 :   return true;
    1087             : }
    1088             : 
    1089             : #define __ gasm()->
    1090             : 
    1091       53379 : Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) {
    1092       53379 :   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
    1093             :   Node* value = node->InputAt(0);
    1094             : 
    1095      106756 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1096       53378 :   auto if_heapnumber = __ MakeDeferredLabel();
    1097       53378 :   auto if_int32 = __ MakeLabel();
    1098             : 
    1099       53378 :   Node* value32 = __ RoundFloat64ToInt32(value);
    1100       53377 :   __ GotoIf(__ Float64Equal(value, __ ChangeInt32ToFloat64(value32)),
    1101       53379 :             &if_int32);
    1102             :   __ Goto(&if_heapnumber);
    1103             : 
    1104             :   __ Bind(&if_int32);
    1105             :   {
    1106       53378 :     if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
    1107       40454 :       Node* zero = __ Int32Constant(0);
    1108       40454 :       auto if_zero = __ MakeDeferredLabel();
    1109       40454 :       auto if_smi = __ MakeLabel();
    1110             : 
    1111       40454 :       __ GotoIf(__ Word32Equal(value32, zero), &if_zero);
    1112             :       __ Goto(&if_smi);
    1113             : 
    1114             :       __ Bind(&if_zero);
    1115             :       {
    1116             :         // In case of 0, we need to check the high bits for the IEEE -0 pattern.
    1117       40454 :         __ GotoIf(__ Int32LessThan(__ Float64ExtractHighWord32(value), zero),
    1118       40454 :                   &if_heapnumber);
    1119             :         __ Goto(&if_smi);
    1120             :       }
    1121             : 
    1122             :       __ Bind(&if_smi);
    1123             :     }
    1124             : 
    1125             :     if (SmiValuesAre32Bits()) {
    1126       53378 :       Node* value_smi = ChangeInt32ToSmi(value32);
    1127             :       __ Goto(&done, value_smi);
    1128             :     } else {
    1129             :       DCHECK(SmiValuesAre31Bits());
    1130             :       Node* add = __ Int32AddWithOverflow(value32, value32);
    1131             :       Node* ovf = __ Projection(1, add);
    1132             :       __ GotoIf(ovf, &if_heapnumber);
    1133             :       Node* value_smi = __ Projection(0, add);
    1134             :       value_smi = ChangeInt32ToIntPtr(value_smi);
    1135             :       __ Goto(&done, value_smi);
    1136             :     }
    1137             :   }
    1138             : 
    1139             :   __ Bind(&if_heapnumber);
    1140             :   {
    1141       53378 :     Node* value_number = AllocateHeapNumberWithValue(value);
    1142             :     __ Goto(&done, value_number);
    1143             :   }
    1144             : 
    1145             :   __ Bind(&done);
    1146       53379 :   return done.PhiAt(0);
    1147             : }
    1148             : 
    1149          91 : Node* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) {
    1150             :   Node* value = node->InputAt(0);
    1151          91 :   return AllocateHeapNumberWithValue(value);
    1152             : }
    1153             : 
    1154        9669 : Node* EffectControlLinearizer::LowerChangeBitToTagged(Node* node) {
    1155             :   Node* value = node->InputAt(0);
    1156             : 
    1157        9669 :   auto if_true = __ MakeLabel();
    1158       19338 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1159             : 
    1160        9669 :   __ GotoIf(value, &if_true);
    1161        9669 :   __ Goto(&done, __ FalseConstant());
    1162             : 
    1163             :   __ Bind(&if_true);
    1164        9669 :   __ Goto(&done, __ TrueConstant());
    1165             : 
    1166             :   __ Bind(&done);
    1167        9669 :   return done.PhiAt(0);
    1168             : }
    1169             : 
    1170       39142 : Node* EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node) {
    1171             :   Node* value = node->InputAt(0);
    1172       39142 :   return ChangeInt32ToSmi(value);
    1173             : }
    1174             : 
    1175       35958 : Node* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) {
    1176             :   Node* value = node->InputAt(0);
    1177             : 
    1178             :   if (SmiValuesAre32Bits()) {
    1179       35958 :     return ChangeInt32ToSmi(value);
    1180             :   }
    1181             :   DCHECK(SmiValuesAre31Bits());
    1182             : 
    1183             :   auto if_overflow = __ MakeDeferredLabel();
    1184             :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1185             : 
    1186             :   Node* add = __ Int32AddWithOverflow(value, value);
    1187             :   Node* ovf = __ Projection(1, add);
    1188             :   __ GotoIf(ovf, &if_overflow);
    1189             :   Node* value_smi = __ Projection(0, add);
    1190             :   value_smi = ChangeInt32ToIntPtr(value_smi);
    1191             :   __ Goto(&done, value_smi);
    1192             : 
    1193             :   __ Bind(&if_overflow);
    1194             :   Node* number = AllocateHeapNumberWithValue(__ ChangeInt32ToFloat64(value));
    1195             :   __ Goto(&done, number);
    1196             : 
    1197             :   __ Bind(&done);
    1198             :   return done.PhiAt(0);
    1199             : }
    1200             : 
    1201          45 : Node* EffectControlLinearizer::LowerChangeInt64ToTagged(Node* node) {
    1202             :   Node* value = node->InputAt(0);
    1203             : 
    1204          45 :   auto if_not_in_smi_range = __ MakeDeferredLabel();
    1205          90 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1206             : 
    1207          45 :   Node* value32 = __ TruncateInt64ToInt32(value);
    1208          45 :   __ GotoIfNot(__ Word64Equal(__ ChangeInt32ToInt64(value32), value),
    1209          45 :                &if_not_in_smi_range);
    1210             : 
    1211             :   if (SmiValuesAre32Bits()) {
    1212             :     Node* value_smi = ChangeInt64ToSmi(value);
    1213             :     __ Goto(&done, value_smi);
    1214             :   } else {
    1215             :     Node* add = __ Int32AddWithOverflow(value32, value32);
    1216             :     Node* ovf = __ Projection(1, add);
    1217             :     __ GotoIf(ovf, &if_not_in_smi_range);
    1218             :     Node* value_smi = ChangeInt32ToIntPtr(__ Projection(0, add));
    1219             :     __ Goto(&done, value_smi);
    1220             :   }
    1221             : 
    1222             :   __ Bind(&if_not_in_smi_range);
    1223          45 :   Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
    1224             :   __ Goto(&done, number);
    1225             : 
    1226             :   __ Bind(&done);
    1227          45 :   return done.PhiAt(0);
    1228             : }
    1229             : 
    1230         639 : Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
    1231             :   Node* value = node->InputAt(0);
    1232             : 
    1233         639 :   auto if_not_in_smi_range = __ MakeDeferredLabel();
    1234        1278 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1235             : 
    1236         639 :   Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
    1237         639 :   __ GotoIfNot(check, &if_not_in_smi_range);
    1238         639 :   __ Goto(&done, ChangeUint32ToSmi(value));
    1239             : 
    1240             :   __ Bind(&if_not_in_smi_range);
    1241         639 :   Node* number = AllocateHeapNumberWithValue(__ ChangeUint32ToFloat64(value));
    1242             : 
    1243             :   __ Goto(&done, number);
    1244             :   __ Bind(&done);
    1245             : 
    1246         639 :   return done.PhiAt(0);
    1247             : }
    1248             : 
    1249          53 : Node* EffectControlLinearizer::LowerChangeUint64ToTagged(Node* node) {
    1250             :   Node* value = node->InputAt(0);
    1251             : 
    1252          53 :   auto if_not_in_smi_range = __ MakeDeferredLabel();
    1253         106 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    1254             : 
    1255             :   Node* check =
    1256          53 :       __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
    1257          53 :   __ GotoIfNot(check, &if_not_in_smi_range);
    1258             :   __ Goto(&done, ChangeInt64ToSmi(value));
    1259             : 
    1260             :   __ Bind(&if_not_in_smi_range);
    1261          53 :   Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
    1262             : 
    1263             :   __ Goto(&done, number);
    1264             :   __ Bind(&done);
    1265             : 
    1266          53 :   return done.PhiAt(0);
    1267             : }
    1268             : 
    1269       49796 : Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) {
    1270             :   Node* value = node->InputAt(0);
    1271       49796 :   return ChangeSmiToInt32(value);
    1272             : }
    1273             : 
    1274         283 : Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt64(Node* node) {
    1275             :   Node* value = node->InputAt(0);
    1276         283 :   return ChangeSmiToInt64(value);
    1277             : }
    1278             : 
    1279      139282 : Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
    1280             :   Node* value = node->InputAt(0);
    1281      139282 :   return __ WordEqual(value, __ TrueConstant());
    1282             : }
    1283             : 
    1284       48010 : void EffectControlLinearizer::TruncateTaggedPointerToBit(
    1285             :     Node* node, GraphAssemblerLabel<1>* done) {
    1286             :   Node* value = node->InputAt(0);
    1287             : 
    1288       48010 :   auto if_heapnumber = __ MakeDeferredLabel();
    1289       48010 :   auto if_bigint = __ MakeDeferredLabel();
    1290             : 
    1291       48010 :   Node* zero = __ Int32Constant(0);
    1292       48010 :   Node* fzero = __ Float64Constant(0.0);
    1293             : 
    1294             :   // Check if {value} is false.
    1295       48010 :   __ GotoIf(__ WordEqual(value, __ FalseConstant()), done, zero);
    1296             : 
    1297             :   // Check if {value} is the empty string.
    1298       48010 :   __ GotoIf(__ WordEqual(value, __ EmptyStringConstant()), done, zero);
    1299             : 
    1300             :   // Load the map of {value}.
    1301       48010 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1302             : 
    1303             :   // Check if the {value} is undetectable and immediately return false.
    1304             :   // This includes undefined and null.
    1305             :   Node* value_map_bitfield =
    1306       48010 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    1307       48010 :   __ GotoIfNot(
    1308             :       __ Word32Equal(
    1309             :           __ Word32And(value_map_bitfield,
    1310             :                        __ Int32Constant(Map::IsUndetectableBit::kMask)),
    1311             :           zero),
    1312       48010 :       done, zero);
    1313             : 
    1314             :   // Check if {value} is a HeapNumber.
    1315       48010 :   __ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()),
    1316       48010 :             &if_heapnumber);
    1317             : 
    1318             :   // Check if {value} is a BigInt.
    1319       48010 :   __ GotoIf(__ WordEqual(value_map, __ BigIntMapConstant()), &if_bigint);
    1320             : 
    1321             :   // All other values that reach here are true.
    1322       48010 :   __ Goto(done, __ Int32Constant(1));
    1323             : 
    1324             :   __ Bind(&if_heapnumber);
    1325             :   {
    1326             :     // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or
    1327             :     // NaN.
    1328             :     Node* value_value =
    1329       48010 :         __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1330       48010 :     __ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
    1331             :   }
    1332             : 
    1333             :   __ Bind(&if_bigint);
    1334             :   {
    1335       48010 :     Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value);
    1336       48010 :     Node* length_is_zero = __ Word32Equal(
    1337             :         __ Word32And(bitfield, __ Int32Constant(BigInt::LengthBits::kMask)),
    1338       48010 :         __ Int32Constant(0));
    1339       48010 :     __ Goto(done, __ Word32Equal(length_is_zero, zero));
    1340             :   }
    1341       48010 : }
    1342             : 
    1343       47616 : Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
    1344       95232 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    1345       47616 :   auto if_smi = __ MakeDeferredLabel();
    1346             : 
    1347             :   Node* value = node->InputAt(0);
    1348       95232 :   __ GotoIf(ObjectIsSmi(value), &if_smi);
    1349             : 
    1350       47616 :   TruncateTaggedPointerToBit(node, &done);
    1351             : 
    1352             :   __ Bind(&if_smi);
    1353             :   {
    1354             :     // If {value} is a Smi, then we only need to check that it's not zero.
    1355       47616 :     __ Goto(&done, __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)),
    1356             :                                   __ Int32Constant(0)));
    1357             :   }
    1358             : 
    1359             :   __ Bind(&done);
    1360       47616 :   return done.PhiAt(0);
    1361             : }
    1362             : 
    1363         394 : Node* EffectControlLinearizer::LowerTruncateTaggedPointerToBit(Node* node) {
    1364         788 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    1365             : 
    1366         394 :   TruncateTaggedPointerToBit(node, &done);
    1367             : 
    1368             :   __ Bind(&done);
    1369         394 :   return done.PhiAt(0);
    1370             : }
    1371             : 
    1372        1756 : Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) {
    1373             :   Node* value = node->InputAt(0);
    1374             : 
    1375        1756 :   auto if_not_smi = __ MakeDeferredLabel();
    1376        3512 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1377             : 
    1378        1756 :   Node* check = ObjectIsSmi(value);
    1379        1756 :   __ GotoIfNot(check, &if_not_smi);
    1380        1756 :   __ Goto(&done, ChangeSmiToInt32(value));
    1381             : 
    1382             :   __ Bind(&if_not_smi);
    1383             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    1384             :                                     Oddball::kToNumberRawOffset);
    1385        1756 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1386        1756 :   vfalse = __ ChangeFloat64ToInt32(vfalse);
    1387             :   __ Goto(&done, vfalse);
    1388             : 
    1389             :   __ Bind(&done);
    1390        1756 :   return done.PhiAt(0);
    1391             : }
    1392             : 
    1393         394 : Node* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) {
    1394             :   Node* value = node->InputAt(0);
    1395             : 
    1396         394 :   auto if_not_smi = __ MakeDeferredLabel();
    1397         788 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1398             : 
    1399         394 :   Node* check = ObjectIsSmi(value);
    1400         394 :   __ GotoIfNot(check, &if_not_smi);
    1401         394 :   __ Goto(&done, ChangeSmiToInt32(value));
    1402             : 
    1403             :   __ Bind(&if_not_smi);
    1404             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    1405             :                                     Oddball::kToNumberRawOffset);
    1406         394 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1407         394 :   vfalse = __ ChangeFloat64ToUint32(vfalse);
    1408             :   __ Goto(&done, vfalse);
    1409             : 
    1410             :   __ Bind(&done);
    1411         394 :   return done.PhiAt(0);
    1412             : }
    1413             : 
    1414           2 : Node* EffectControlLinearizer::LowerChangeTaggedToInt64(Node* node) {
    1415             :   Node* value = node->InputAt(0);
    1416             : 
    1417           2 :   auto if_not_smi = __ MakeDeferredLabel();
    1418           4 :   auto done = __ MakeLabel(MachineRepresentation::kWord64);
    1419             : 
    1420           2 :   Node* check = ObjectIsSmi(value);
    1421           2 :   __ GotoIfNot(check, &if_not_smi);
    1422           2 :   __ Goto(&done, ChangeSmiToInt64(value));
    1423             : 
    1424             :   __ Bind(&if_not_smi);
    1425             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    1426             :                                     Oddball::kToNumberRawOffset);
    1427           2 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1428           2 :   vfalse = __ ChangeFloat64ToInt64(vfalse);
    1429             :   __ Goto(&done, vfalse);
    1430             : 
    1431             :   __ Bind(&done);
    1432           2 :   return done.PhiAt(0);
    1433             : }
    1434             : 
    1435           0 : Node* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) {
    1436       11269 :   return LowerTruncateTaggedToFloat64(node);
    1437             : }
    1438             : 
    1439          14 : Node* EffectControlLinearizer::LowerChangeTaggedToTaggedSigned(Node* node) {
    1440             :   Node* value = node->InputAt(0);
    1441             : 
    1442          14 :   auto if_not_smi = __ MakeDeferredLabel();
    1443          28 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1444             : 
    1445          14 :   Node* check = ObjectIsSmi(value);
    1446          14 :   __ GotoIfNot(check, &if_not_smi);
    1447             :   __ Goto(&done, value);
    1448             : 
    1449             :   __ Bind(&if_not_smi);
    1450             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    1451             :                                     Oddball::kToNumberRawOffset);
    1452          14 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1453          14 :   vfalse = __ ChangeFloat64ToInt32(vfalse);
    1454          14 :   vfalse = ChangeInt32ToSmi(vfalse);
    1455             :   __ Goto(&done, vfalse);
    1456             : 
    1457             :   __ Bind(&done);
    1458          14 :   return done.PhiAt(0);
    1459             : }
    1460             : 
    1461           0 : Node* EffectControlLinearizer::LowerChangeCompressedToTaggedSigned(Node* node) {
    1462             :   Node* value = node->InputAt(0);
    1463             : 
    1464           0 :   auto if_not_smi = __ MakeDeferredLabel();
    1465           0 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1466             : 
    1467           0 :   Node* check = ObjectIsSmi(value);
    1468           0 :   __ GotoIfNot(check, &if_not_smi);
    1469           0 :   __ Goto(&done, __ ChangeCompressedSignedToTaggedSigned(value));
    1470             : 
    1471             :   __ Bind(&if_not_smi);
    1472             :   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
    1473           0 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(),
    1474           0 :                               __ ChangeCompressedToTagged(value));
    1475           0 :   vfalse = __ ChangeFloat64ToInt32(vfalse);
    1476           0 :   vfalse = ChangeInt32ToSmi(vfalse);
    1477             :   __ Goto(&done, vfalse);
    1478             : 
    1479             :   __ Bind(&done);
    1480           0 :   return done.PhiAt(0);
    1481             : }
    1482             : 
    1483           0 : Node* EffectControlLinearizer::LowerChangeTaggedToCompressedSigned(Node* node) {
    1484             :   Node* value = node->InputAt(0);
    1485             : 
    1486           0 :   auto if_not_smi = __ MakeDeferredLabel();
    1487           0 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1488             : 
    1489           0 :   Node* check = ObjectIsSmi(value);
    1490           0 :   __ GotoIfNot(check, &if_not_smi);
    1491           0 :   __ Goto(&done, __ ChangeTaggedSignedToCompressedSigned(value));
    1492             : 
    1493             :   __ Bind(&if_not_smi);
    1494             :   STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
    1495           0 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1496           0 :   vfalse = __ ChangeFloat64ToInt32(vfalse);
    1497           0 :   vfalse = ChangeInt32ToSmi(vfalse);
    1498           0 :   vfalse = __ ChangeTaggedSignedToCompressedSigned(vfalse);
    1499             :   __ Goto(&done, vfalse);
    1500             : 
    1501             :   __ Bind(&done);
    1502           0 :   return done.PhiAt(0);
    1503             : }
    1504             : 
    1505       11996 : Node* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) {
    1506             :   Node* value = node->InputAt(0);
    1507             : 
    1508       11996 :   auto if_not_smi = __ MakeDeferredLabel();
    1509       23992 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    1510             : 
    1511       11996 :   Node* check = ObjectIsSmi(value);
    1512       11996 :   __ GotoIfNot(check, &if_not_smi);
    1513       11996 :   Node* vtrue = ChangeSmiToInt32(value);
    1514       11996 :   vtrue = __ ChangeInt32ToFloat64(vtrue);
    1515             :   __ Goto(&done, vtrue);
    1516             : 
    1517             :   __ Bind(&if_not_smi);
    1518             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    1519             :                                     Oddball::kToNumberRawOffset);
    1520       11996 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    1521             :   __ Goto(&done, vfalse);
    1522             : 
    1523             :   __ Bind(&done);
    1524       11996 :   return done.PhiAt(0);
    1525             : }
    1526             : 
    1527        1024 : Node* EffectControlLinearizer::LowerPoisonIndex(Node* node) {
    1528             :   Node* index = node->InputAt(0);
    1529        1024 :   if (mask_array_index_ == kMaskArrayIndex) {
    1530           0 :     index = __ Word32PoisonOnSpeculation(index);
    1531             :   }
    1532        1024 :   return index;
    1533             : }
    1534             : 
    1535       51347 : void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
    1536       51347 :   CheckMapsParameters const& p = CheckMapsParametersOf(node->op());
    1537             :   Node* value = node->InputAt(0);
    1538             : 
    1539             :   ZoneHandleSet<Map> const& maps = p.maps();
    1540             :   size_t const map_count = maps.size();
    1541             : 
    1542       51347 :   if (p.flags() & CheckMapsFlag::kTryMigrateInstance) {
    1543          41 :     auto done = __ MakeLabel();
    1544          41 :     auto migrate = __ MakeDeferredLabel();
    1545             : 
    1546             :     // Load the current map of the {value}.
    1547          82 :     Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1548             : 
    1549             :     // Perform the map checks.
    1550         129 :     for (size_t i = 0; i < map_count; ++i) {
    1551          44 :       Node* map = __ HeapConstant(maps[i]);
    1552          44 :       Node* check = __ WordEqual(value_map, map);
    1553          44 :       if (i == map_count - 1) {
    1554          41 :         __ Branch(check, &done, &migrate, IsSafetyCheck::kCriticalSafetyCheck);
    1555             :       } else {
    1556           3 :         auto next_map = __ MakeLabel();
    1557           3 :         __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
    1558             :         __ Bind(&next_map);
    1559             :       }
    1560             :     }
    1561             : 
    1562             :     // Perform the (deferred) instance migration.
    1563             :     __ Bind(&migrate);
    1564             :     {
    1565             :       // If map is not deprecated the migration attempt does not make sense.
    1566             :       Node* bitfield3 =
    1567          41 :           __ LoadField(AccessBuilder::ForMapBitField3(), value_map);
    1568          41 :       Node* if_not_deprecated = __ WordEqual(
    1569             :           __ Word32And(bitfield3,
    1570             :                        __ Int32Constant(Map::IsDeprecatedBit::kMask)),
    1571          41 :           __ Int32Constant(0));
    1572             :       __ DeoptimizeIf(DeoptimizeReason::kWrongMap, p.feedback(),
    1573             :                       if_not_deprecated, frame_state,
    1574          41 :                       IsSafetyCheck::kCriticalSafetyCheck);
    1575             : 
    1576          41 :       Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    1577             :       Runtime::FunctionId id = Runtime::kTryMigrateInstance;
    1578          41 :       auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    1579          41 :           graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
    1580          41 :       Node* result = __ Call(call_descriptor, __ CEntryStubConstant(1), value,
    1581             :                              __ ExternalConstant(ExternalReference::Create(id)),
    1582          41 :                              __ Int32Constant(1), __ NoContextConstant());
    1583          41 :       Node* check = ObjectIsSmi(result);
    1584             :       __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, p.feedback(),
    1585          41 :                       check, frame_state, IsSafetyCheck::kCriticalSafetyCheck);
    1586             :     }
    1587             : 
    1588             :     // Reload the current map of the {value}.
    1589          41 :     value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1590             : 
    1591             :     // Perform the map checks again.
    1592         129 :     for (size_t i = 0; i < map_count; ++i) {
    1593          44 :       Node* map = __ HeapConstant(maps[i]);
    1594          44 :       Node* check = __ WordEqual(value_map, map);
    1595          44 :       if (i == map_count - 1) {
    1596             :         __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
    1597          41 :                            frame_state, IsSafetyCheck::kCriticalSafetyCheck);
    1598             :       } else {
    1599           3 :         auto next_map = __ MakeLabel();
    1600           3 :         __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
    1601             :         __ Bind(&next_map);
    1602             :       }
    1603             :     }
    1604             : 
    1605             :     __ Goto(&done);
    1606             :     __ Bind(&done);
    1607             :   } else {
    1608       51306 :     auto done = __ MakeLabel();
    1609             : 
    1610             :     // Load the current map of the {value}.
    1611             :     Node* value_map =
    1612             :         UsingCompressedPointers()
    1613             :             ? __ LoadField(AccessBuilder::ForCompressedMap(), value)
    1614      102612 :             : __ LoadField(AccessBuilder::ForMap(), value);
    1615             : 
    1616      165676 :     for (size_t i = 0; i < map_count; ++i) {
    1617             :       Node* check;
    1618             : 
    1619             :       if (UsingCompressedPointers()) {
    1620             :         // We need the dereference scope to embed the map pointer value as an
    1621             :         // int32. We don't visit the pointer.
    1622             :         AllowHandleDereference allow_map_dereference;
    1623             :         int32_t int32Map = static_cast<int32_t>(CompressTagged(maps[i]->ptr()));
    1624             :         Node* map = __ Int32Constant(int32Map);
    1625             :         check = __ Word32Equal(value_map, map);
    1626             :         this->embedded_maps()->push_back(maps[i]);
    1627             :       } else {
    1628       57185 :         Node* map = __ HeapConstant(maps[i]);
    1629       57185 :         check = __ WordEqual(value_map, map);
    1630             :       }
    1631             : 
    1632       57185 :       if (i == map_count - 1) {
    1633             :         __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
    1634       51306 :                            frame_state, IsSafetyCheck::kCriticalSafetyCheck);
    1635             :       } else {
    1636        5879 :         auto next_map = __ MakeLabel();
    1637        5879 :         __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
    1638             :         __ Bind(&next_map);
    1639             :       }
    1640             :     }
    1641             :     __ Goto(&done);
    1642             :     __ Bind(&done);
    1643             :   }
    1644       51347 : }
    1645             : 
    1646        7413 : Node* EffectControlLinearizer::LowerCompareMaps(Node* node) {
    1647        7413 :   ZoneHandleSet<Map> const& maps = CompareMapsParametersOf(node->op());
    1648             :   size_t const map_count = maps.size();
    1649             :   Node* value = node->InputAt(0);
    1650             : 
    1651       14826 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    1652             : 
    1653             :   // Load the current map of the {value}.
    1654             :   Node* value_map = UsingCompressedPointers()
    1655             :                         ? __ LoadField(AccessBuilder::ForCompressedMap(), value)
    1656       14826 :                         : __ LoadField(AccessBuilder::ForMap(), value);
    1657             : 
    1658       22255 :   for (size_t i = 0; i < map_count; ++i) {
    1659             :     Node* check;
    1660             : 
    1661             :     if (UsingCompressedPointers()) {
    1662             :       // We need the dereference scope to embed the map pointer value as an
    1663             :       // int32. We don't visit the pointer.
    1664             :       AllowHandleDereference allow_map_dereference;
    1665             :       int32_t int32Map = static_cast<int32_t>(CompressTagged(maps[i]->ptr()));
    1666             :       Node* map = __ Int32Constant(int32Map);
    1667             :       check = __ Word32Equal(value_map, map);
    1668             :       this->embedded_maps()->push_back(maps[i]);
    1669             :     } else {
    1670        7421 :       Node* map = __ HeapConstant(maps[i]);
    1671        7421 :       check = __ WordEqual(value_map, map);
    1672             :     }
    1673             : 
    1674        7421 :     auto next_map = __ MakeLabel();
    1675        7421 :     auto passed = __ MakeLabel();
    1676        7421 :     __ Branch(check, &passed, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
    1677             : 
    1678             :     __ Bind(&passed);
    1679        7421 :     __ Goto(&done, __ Int32Constant(1));
    1680             : 
    1681             :     __ Bind(&next_map);
    1682             :   }
    1683        7413 :   __ Goto(&done, __ Int32Constant(0));
    1684             : 
    1685             :   __ Bind(&done);
    1686        7413 :   return done.PhiAt(0);
    1687             : }
    1688             : 
    1689         474 : Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) {
    1690             :   Node* value = node->InputAt(0);
    1691         474 :   const CheckParameters& params = CheckParametersOf(node->op());
    1692             : 
    1693         474 :   auto if_not_smi = __ MakeDeferredLabel();
    1694         474 :   auto done = __ MakeLabel();
    1695             : 
    1696         474 :   Node* check0 = ObjectIsSmi(value);
    1697         474 :   __ GotoIfNot(check0, &if_not_smi);
    1698             :   __ Goto(&done);
    1699             : 
    1700             :   __ Bind(&if_not_smi);
    1701         474 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1702         474 :   Node* check1 = __ WordEqual(value_map, __ HeapNumberMapConstant());
    1703             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
    1704         474 :                      check1, frame_state);
    1705             :   __ Goto(&done);
    1706             : 
    1707             :   __ Bind(&done);
    1708         474 :   return value;
    1709             : }
    1710             : 
    1711         809 : Node* EffectControlLinearizer::LowerCheckReceiver(Node* node,
    1712             :                                                   Node* frame_state) {
    1713             :   Node* value = node->InputAt(0);
    1714             : 
    1715        1618 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1716             :   Node* value_instance_type =
    1717         809 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    1718             : 
    1719             :   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    1720         809 :   Node* check = __ Uint32LessThanOrEqual(
    1721         809 :       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
    1722        1618 :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObject, VectorSlotPair(),
    1723         809 :                      check, frame_state);
    1724         809 :   return value;
    1725             : }
    1726             : 
    1727          72 : Node* EffectControlLinearizer::LowerCheckReceiverOrNullOrUndefined(
    1728             :     Node* node, Node* frame_state) {
    1729             :   Node* value = node->InputAt(0);
    1730             : 
    1731         144 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1732             :   Node* value_instance_type =
    1733          72 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    1734             : 
    1735             :   // Rule out all primitives except oddballs (true, false, undefined, null).
    1736             :   STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE);
    1737             :   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    1738          72 :   Node* check0 = __ Uint32LessThanOrEqual(__ Uint32Constant(ODDBALL_TYPE),
    1739          72 :                                           value_instance_type);
    1740         144 :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObjectOrNullOrUndefined,
    1741          72 :                      VectorSlotPair(), check0, frame_state);
    1742             : 
    1743             :   // Rule out booleans.
    1744          72 :   Node* check1 = __ WordEqual(value_map, __ BooleanMapConstant());
    1745         144 :   __ DeoptimizeIf(DeoptimizeReason::kNotAJavaScriptObjectOrNullOrUndefined,
    1746          72 :                   VectorSlotPair(), check1, frame_state);
    1747          72 :   return value;
    1748             : }
    1749             : 
    1750          32 : Node* EffectControlLinearizer::LowerCheckSymbol(Node* node, Node* frame_state) {
    1751             :   Node* value = node->InputAt(0);
    1752             : 
    1753          64 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1754             : 
    1755             :   Node* check =
    1756          32 :       __ WordEqual(value_map, __ HeapConstant(factory()->symbol_map()));
    1757          64 :   __ DeoptimizeIfNot(DeoptimizeReason::kNotASymbol, VectorSlotPair(), check,
    1758          32 :                      frame_state);
    1759          32 :   return value;
    1760             : }
    1761             : 
    1762        6287 : Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) {
    1763             :   Node* value = node->InputAt(0);
    1764        6287 :   const CheckParameters& params = CheckParametersOf(node->op());
    1765             : 
    1766       12574 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1767             :   Node* value_instance_type =
    1768        6287 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    1769             : 
    1770        6287 :   Node* check = __ Uint32LessThan(value_instance_type,
    1771        6287 :                                   __ Uint32Constant(FIRST_NONSTRING_TYPE));
    1772             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAString, params.feedback(), check,
    1773        6287 :                      frame_state);
    1774        6287 :   return value;
    1775             : }
    1776             : 
    1777        1395 : Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node,
    1778             :                                                             Node* frame_state) {
    1779             :   Node* value = node->InputAt(0);
    1780             : 
    1781        2790 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    1782             :   Node* value_instance_type =
    1783        1395 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    1784             : 
    1785        1395 :   Node* check = __ Word32Equal(
    1786             :       __ Word32And(value_instance_type,
    1787             :                    __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)),
    1788        1395 :       __ Int32Constant(kInternalizedTag));
    1789        2790 :   __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, VectorSlotPair(),
    1790        1395 :                      check, frame_state);
    1791             : 
    1792        1395 :   return value;
    1793             : }
    1794             : 
    1795       14522 : void EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
    1796             :   Node* value = node->InputAt(0);
    1797       14522 :   const CheckIfParameters& p = CheckIfParametersOf(node->op());
    1798       14522 :   __ DeoptimizeIfNot(p.reason(), p.feedback(), value, frame_state);
    1799       14522 : }
    1800             : 
    1801       20902 : Node* EffectControlLinearizer::LowerStringConcat(Node* node) {
    1802             :   Node* lhs = node->InputAt(1);
    1803             :   Node* rhs = node->InputAt(2);
    1804             : 
    1805             :   Callable const callable =
    1806       20902 :       CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE);
    1807       20902 :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    1808       20902 :       graph()->zone(), callable.descriptor(),
    1809             :       callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
    1810       20902 :       Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow);
    1811             : 
    1812             :   Node* value =
    1813       62706 :       __ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs,
    1814       20902 :               rhs, __ NoContextConstant());
    1815             : 
    1816       20902 :   return value;
    1817             : }
    1818             : 
    1819       55849 : Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
    1820             :                                                     Node* frame_state) {
    1821             :   Node* lhs = node->InputAt(0);
    1822             :   Node* rhs = node->InputAt(1);
    1823             : 
    1824       55849 :   Node* value = __ Int32AddWithOverflow(lhs, rhs);
    1825       55843 :   Node* check = __ Projection(1, value);
    1826      111697 :   __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check,
    1827       55848 :                   frame_state);
    1828       55849 :   return __ Projection(0, value);
    1829             : }
    1830             : 
    1831        7611 : Node* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node,
    1832             :                                                     Node* frame_state) {
    1833             :   Node* lhs = node->InputAt(0);
    1834             :   Node* rhs = node->InputAt(1);
    1835             : 
    1836        7611 :   Node* value = __ Int32SubWithOverflow(lhs, rhs);
    1837        7611 :   Node* check = __ Projection(1, value);
    1838       15222 :   __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check,
    1839        7611 :                   frame_state);
    1840        7611 :   return __ Projection(0, value);
    1841             : }
    1842             : 
    1843         243 : Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
    1844             :                                                     Node* frame_state) {
    1845             :   Node* lhs = node->InputAt(0);
    1846             :   Node* rhs = node->InputAt(1);
    1847         243 :   Node* zero = __ Int32Constant(0);
    1848             : 
    1849             :   // Check if the {rhs} is a known power of two.
    1850             :   Int32Matcher m(rhs);
    1851         243 :   if (m.IsPowerOf2()) {
    1852             :     // Since we know that {rhs} is a power of two, we can perform a fast
    1853             :     // check to see if the relevant least significant bits of the {lhs}
    1854             :     // are all zero, and if so we know that we can perform a division
    1855             :     // safely (and fast by doing an arithmetic - aka sign preserving -
    1856             :     // right shift on {lhs}).
    1857             :     int32_t divisor = m.Value();
    1858         142 :     Node* mask = __ Int32Constant(divisor - 1);
    1859         142 :     Node* shift = __ Int32Constant(WhichPowerOf2(divisor));
    1860         142 :     Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
    1861         284 :     __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
    1862         142 :                        check, frame_state);
    1863         142 :     return __ Word32Sar(lhs, shift);
    1864             :   } else {
    1865         101 :     auto if_rhs_positive = __ MakeLabel();
    1866         101 :     auto if_rhs_negative = __ MakeDeferredLabel();
    1867         202 :     auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1868             : 
    1869             :     // Check if {rhs} is positive (and not zero).
    1870         101 :     Node* check_rhs_positive = __ Int32LessThan(zero, rhs);
    1871         101 :     __ Branch(check_rhs_positive, &if_rhs_positive, &if_rhs_negative);
    1872             : 
    1873             :     __ Bind(&if_rhs_positive);
    1874             :     {
    1875             :       // Fast case, no additional checking required.
    1876         101 :       __ Goto(&done, __ Int32Div(lhs, rhs));
    1877             :     }
    1878             : 
    1879             :     __ Bind(&if_rhs_negative);
    1880             :     {
    1881         101 :       auto if_lhs_minint = __ MakeDeferredLabel();
    1882         101 :       auto if_lhs_notminint = __ MakeLabel();
    1883             : 
    1884             :       // Check if {rhs} is zero.
    1885         101 :       Node* check_rhs_zero = __ Word32Equal(rhs, zero);
    1886         202 :       __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(),
    1887         101 :                       check_rhs_zero, frame_state);
    1888             : 
    1889             :       // Check if {lhs} is zero, as that would produce minus zero.
    1890         101 :       Node* check_lhs_zero = __ Word32Equal(lhs, zero);
    1891         202 :       __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(),
    1892         101 :                       check_lhs_zero, frame_state);
    1893             : 
    1894             :       // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
    1895             :       // to return -kMinInt, which is not representable as Word32.
    1896         202 :       Node* check_lhs_minint = graph()->NewNode(machine()->Word32Equal(), lhs,
    1897             :                                                 __ Int32Constant(kMinInt));
    1898         101 :       __ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint);
    1899             : 
    1900             :       __ Bind(&if_lhs_minint);
    1901             :       {
    1902             :         // Check that {rhs} is not -1, otherwise result would be -kMinInt.
    1903         101 :         Node* check_rhs_minusone = __ Word32Equal(rhs, __ Int32Constant(-1));
    1904         202 :         __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(),
    1905         101 :                         check_rhs_minusone, frame_state);
    1906             : 
    1907             :         // Perform the actual integer division.
    1908         101 :         __ Goto(&done, __ Int32Div(lhs, rhs));
    1909             :       }
    1910             : 
    1911             :       __ Bind(&if_lhs_notminint);
    1912             :       {
    1913             :         // Perform the actual integer division.
    1914         101 :         __ Goto(&done, __ Int32Div(lhs, rhs));
    1915             :       }
    1916             :     }
    1917             : 
    1918             :     __ Bind(&done);
    1919             :     Node* value = done.PhiAt(0);
    1920             : 
    1921             :     // Check if the remainder is non-zero.
    1922         101 :     Node* check = __ Word32Equal(lhs, __ Int32Mul(value, rhs));
    1923         202 :     __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
    1924         101 :                        check, frame_state);
    1925             : 
    1926             :     return value;
    1927             :   }
    1928             : }
    1929             : 
    1930         859 : Node* EffectControlLinearizer::BuildUint32Mod(Node* lhs, Node* rhs) {
    1931         859 :   auto if_rhs_power_of_two = __ MakeLabel();
    1932        1718 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1933             : 
    1934             :   // Compute the mask for the {rhs}.
    1935         859 :   Node* one = __ Int32Constant(1);
    1936         859 :   Node* msk = __ Int32Sub(rhs, one);
    1937             : 
    1938             :   // Check if the {rhs} is a power of two.
    1939         859 :   __ GotoIf(__ Word32Equal(__ Word32And(rhs, msk), __ Int32Constant(0)),
    1940         859 :             &if_rhs_power_of_two);
    1941             :   {
    1942             :     // The {rhs} is not a power of two, do a generic Uint32Mod.
    1943         859 :     __ Goto(&done, __ Uint32Mod(lhs, rhs));
    1944             :   }
    1945             : 
    1946             :   __ Bind(&if_rhs_power_of_two);
    1947             :   {
    1948             :     // The {rhs} is a power of two, just do a fast bit masking.
    1949         859 :     __ Goto(&done, __ Word32And(lhs, msk));
    1950             :   }
    1951             : 
    1952             :   __ Bind(&done);
    1953         859 :   return done.PhiAt(0);
    1954             : }
    1955             : 
    1956         822 : Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node,
    1957             :                                                     Node* frame_state) {
    1958             :   // General case for signed integer modulus, with optimization for (unknown)
    1959             :   // power of 2 right hand side.
    1960             :   //
    1961             :   //   if rhs <= 0 then
    1962             :   //     rhs = -rhs
    1963             :   //     deopt if rhs == 0
    1964             :   //   let msk = rhs - 1 in
    1965             :   //   if lhs < 0 then
    1966             :   //     let lhs_abs = -lsh in
    1967             :   //     let res = if rhs & msk == 0 then
    1968             :   //                 lhs_abs & msk
    1969             :   //               else
    1970             :   //                 lhs_abs % rhs in
    1971             :   //     if lhs < 0 then
    1972             :   //       deopt if res == 0
    1973             :   //       -res
    1974             :   //     else
    1975             :   //       res
    1976             :   //   else
    1977             :   //     if rhs & msk == 0 then
    1978             :   //       lhs & msk
    1979             :   //     else
    1980             :   //       lhs % rhs
    1981             :   //
    1982             :   Node* lhs = node->InputAt(0);
    1983             :   Node* rhs = node->InputAt(1);
    1984             : 
    1985         822 :   auto if_rhs_not_positive = __ MakeDeferredLabel();
    1986         822 :   auto if_lhs_negative = __ MakeDeferredLabel();
    1987             :   auto if_rhs_power_of_two = __ MakeLabel();
    1988        1644 :   auto rhs_checked = __ MakeLabel(MachineRepresentation::kWord32);
    1989        1644 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    1990             : 
    1991         822 :   Node* zero = __ Int32Constant(0);
    1992             : 
    1993             :   // Check if {rhs} is not strictly positive.
    1994         822 :   Node* check0 = __ Int32LessThanOrEqual(rhs, zero);
    1995         822 :   __ GotoIf(check0, &if_rhs_not_positive);
    1996             :   __ Goto(&rhs_checked, rhs);
    1997             : 
    1998             :   __ Bind(&if_rhs_not_positive);
    1999             :   {
    2000             :     // Negate {rhs}, might still produce a negative result in case of
    2001             :     // -2^31, but that is handled safely below.
    2002         822 :     Node* vtrue0 = __ Int32Sub(zero, rhs);
    2003             : 
    2004             :     // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
    2005        1644 :     __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(),
    2006         822 :                     __ Word32Equal(vtrue0, zero), frame_state);
    2007             :     __ Goto(&rhs_checked, vtrue0);
    2008             :   }
    2009             : 
    2010             :   __ Bind(&rhs_checked);
    2011             :   rhs = rhs_checked.PhiAt(0);
    2012             : 
    2013         822 :   __ GotoIf(__ Int32LessThan(lhs, zero), &if_lhs_negative);
    2014             :   {
    2015             :     // The {lhs} is a non-negative integer.
    2016         822 :     __ Goto(&done, BuildUint32Mod(lhs, rhs));
    2017             :   }
    2018             : 
    2019             :   __ Bind(&if_lhs_negative);
    2020             :   {
    2021             :     // The {lhs} is a negative integer. This is very unlikely and
    2022             :     // we intentionally don't use the BuildUint32Mod() here, which
    2023             :     // would try to figure out whether {rhs} is a power of two,
    2024             :     // since this is intended to be a slow-path.
    2025         822 :     Node* res = __ Uint32Mod(__ Int32Sub(zero, lhs), rhs);
    2026             : 
    2027             :     // Check if we would have to return -0.
    2028        1644 :     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(),
    2029         822 :                     __ Word32Equal(res, zero), frame_state);
    2030         822 :     __ Goto(&done, __ Int32Sub(zero, res));
    2031             :   }
    2032             : 
    2033             :   __ Bind(&done);
    2034         822 :   return done.PhiAt(0);
    2035             : }
    2036             : 
    2037          52 : Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node,
    2038             :                                                      Node* frame_state) {
    2039             :   Node* lhs = node->InputAt(0);
    2040             :   Node* rhs = node->InputAt(1);
    2041          52 :   Node* zero = __ Int32Constant(0);
    2042             : 
    2043             :   // Check if the {rhs} is a known power of two.
    2044             :   Uint32Matcher m(rhs);
    2045          52 :   if (m.IsPowerOf2()) {
    2046             :     // Since we know that {rhs} is a power of two, we can perform a fast
    2047             :     // check to see if the relevant least significant bits of the {lhs}
    2048             :     // are all zero, and if so we know that we can perform a division
    2049             :     // safely (and fast by doing a logical - aka zero extending - right
    2050             :     // shift on {lhs}).
    2051             :     uint32_t divisor = m.Value();
    2052          41 :     Node* mask = __ Uint32Constant(divisor - 1);
    2053          41 :     Node* shift = __ Uint32Constant(WhichPowerOf2(divisor));
    2054          41 :     Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
    2055          82 :     __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
    2056          41 :                        check, frame_state);
    2057          41 :     return __ Word32Shr(lhs, shift);
    2058             :   } else {
    2059             :     // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
    2060          11 :     Node* check = __ Word32Equal(rhs, zero);
    2061          22 :     __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check,
    2062          11 :                     frame_state);
    2063             : 
    2064             :     // Perform the actual unsigned integer division.
    2065          11 :     Node* value = __ Uint32Div(lhs, rhs);
    2066             : 
    2067             :     // Check if the remainder is non-zero.
    2068          11 :     check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
    2069          22 :     __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
    2070          11 :                        check, frame_state);
    2071          11 :     return value;
    2072             :   }
    2073             : }
    2074             : 
    2075          37 : Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node,
    2076             :                                                      Node* frame_state) {
    2077             :   Node* lhs = node->InputAt(0);
    2078             :   Node* rhs = node->InputAt(1);
    2079             : 
    2080          37 :   Node* zero = __ Int32Constant(0);
    2081             : 
    2082             :   // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
    2083          37 :   Node* check = __ Word32Equal(rhs, zero);
    2084          74 :   __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check,
    2085          37 :                   frame_state);
    2086             : 
    2087             :   // Perform the actual unsigned integer modulus.
    2088          37 :   return BuildUint32Mod(lhs, rhs);
    2089             : }
    2090             : 
    2091        5819 : Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node,
    2092             :                                                     Node* frame_state) {
    2093        5819 :   CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
    2094             :   Node* lhs = node->InputAt(0);
    2095             :   Node* rhs = node->InputAt(1);
    2096             : 
    2097        5819 :   Node* projection = __ Int32MulWithOverflow(lhs, rhs);
    2098        5819 :   Node* check = __ Projection(1, projection);
    2099       11638 :   __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check,
    2100        5819 :                   frame_state);
    2101             : 
    2102        5819 :   Node* value = __ Projection(0, projection);
    2103             : 
    2104        5819 :   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
    2105        3932 :     auto if_zero = __ MakeDeferredLabel();
    2106        3932 :     auto check_done = __ MakeLabel();
    2107        3932 :     Node* zero = __ Int32Constant(0);
    2108        3932 :     Node* check_zero = __ Word32Equal(value, zero);
    2109        3932 :     __ GotoIf(check_zero, &if_zero);
    2110             :     __ Goto(&check_done);
    2111             : 
    2112             :     __ Bind(&if_zero);
    2113             :     // We may need to return negative zero.
    2114        3932 :     Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero);
    2115        7864 :     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(), check_or,
    2116        3932 :                     frame_state);
    2117             :     __ Goto(&check_done);
    2118             : 
    2119             :     __ Bind(&check_done);
    2120             :   }
    2121             : 
    2122        5819 :   return value;
    2123             : }
    2124             : 
    2125           0 : Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
    2126             :     Node* node, Node* frame_state) {
    2127             :   DCHECK(SmiValuesAre31Bits());
    2128             :   Node* value = node->InputAt(0);
    2129           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2130             : 
    2131           0 :   Node* add = __ Int32AddWithOverflow(value, value);
    2132           0 :   Node* check = __ Projection(1, add);
    2133             :   __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2134           0 :                   frame_state);
    2135           0 :   Node* result = __ Projection(0, add);
    2136             :   result = ChangeInt32ToIntPtr(result);
    2137           0 :   return result;
    2138             : }
    2139             : 
    2140           9 : Node* EffectControlLinearizer::LowerCheckedInt64ToInt32(Node* node,
    2141             :                                                         Node* frame_state) {
    2142             :   Node* value = node->InputAt(0);
    2143           9 :   const CheckParameters& params = CheckParametersOf(node->op());
    2144             : 
    2145           9 :   Node* value32 = __ TruncateInt64ToInt32(value);
    2146           9 :   Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
    2147             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2148           9 :                      frame_state);
    2149           9 :   return value32;
    2150             : }
    2151             : 
    2152         151 : Node* EffectControlLinearizer::LowerCheckedInt64ToTaggedSigned(
    2153             :     Node* node, Node* frame_state) {
    2154             :   Node* value = node->InputAt(0);
    2155         151 :   const CheckParameters& params = CheckParametersOf(node->op());
    2156             : 
    2157         151 :   Node* value32 = __ TruncateInt64ToInt32(value);
    2158         151 :   Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
    2159             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2160         151 :                      frame_state);
    2161             : 
    2162             :   if (SmiValuesAre32Bits()) {
    2163             :     return ChangeInt64ToSmi(value);
    2164             :   } else {
    2165             :     Node* add = __ Int32AddWithOverflow(value32, value32);
    2166             :     Node* check = __ Projection(1, add);
    2167             :     __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2168             :                     frame_state);
    2169             :     Node* result = __ Projection(0, add);
    2170             :     result = ChangeInt32ToIntPtr(result);
    2171             :     return result;
    2172             :   }
    2173             : }
    2174             : 
    2175       52521 : Node* EffectControlLinearizer::LowerCheckedUint32Bounds(Node* node,
    2176             :                                                         Node* frame_state) {
    2177             :   Node* index = node->InputAt(0);
    2178             :   Node* limit = node->InputAt(1);
    2179       52521 :   const CheckBoundsParameters& params = CheckBoundsParametersOf(node->op());
    2180             : 
    2181       52521 :   Node* check = __ Uint32LessThan(index, limit);
    2182       52521 :   switch (params.mode()) {
    2183             :     case CheckBoundsParameters::kDeoptOnOutOfBounds:
    2184             :       __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds,
    2185             :                          params.check_parameters().feedback(), check,
    2186       47932 :                          frame_state, IsSafetyCheck::kCriticalSafetyCheck);
    2187       47932 :       break;
    2188             :     case CheckBoundsParameters::kAbortOnOutOfBounds: {
    2189        4589 :       auto if_abort = __ MakeDeferredLabel();
    2190        4589 :       auto done = __ MakeLabel();
    2191             : 
    2192        4589 :       __ Branch(check, &done, &if_abort);
    2193             : 
    2194             :       __ Bind(&if_abort);
    2195        4589 :       __ Unreachable();
    2196             :       __ Goto(&done);
    2197             : 
    2198             :       __ Bind(&done);
    2199             :       break;
    2200             :     }
    2201             :   }
    2202             : 
    2203       52521 :   return index;
    2204             : }
    2205             : 
    2206         386 : Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
    2207             :                                                          Node* frame_state) {
    2208             :   Node* value = node->InputAt(0);
    2209         386 :   const CheckParameters& params = CheckParametersOf(node->op());
    2210         386 :   Node* unsafe = __ Int32LessThan(value, __ Int32Constant(0));
    2211             :   __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), unsafe,
    2212         386 :                   frame_state);
    2213         386 :   return value;
    2214             : }
    2215             : 
    2216           7 : Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
    2217             :     Node* node, Node* frame_state) {
    2218             :   Node* value = node->InputAt(0);
    2219           7 :   const CheckParameters& params = CheckParametersOf(node->op());
    2220           7 :   Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
    2221             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2222           7 :                      frame_state);
    2223           7 :   return ChangeUint32ToSmi(value);
    2224             : }
    2225             : 
    2226         195 : Node* EffectControlLinearizer::LowerCheckedUint64Bounds(Node* node,
    2227             :                                                         Node* frame_state) {
    2228         195 :   CheckParameters const& params = CheckParametersOf(node->op());
    2229             :   Node* const index = node->InputAt(0);
    2230             :   Node* const limit = node->InputAt(1);
    2231             : 
    2232         195 :   Node* check = __ Uint64LessThan(index, limit);
    2233             :   __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds, params.feedback(), check,
    2234         195 :                      frame_state, IsSafetyCheck::kCriticalSafetyCheck);
    2235         195 :   return index;
    2236             : }
    2237             : 
    2238           0 : Node* EffectControlLinearizer::LowerCheckedUint64ToInt32(Node* node,
    2239             :                                                          Node* frame_state) {
    2240             :   Node* value = node->InputAt(0);
    2241           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2242             : 
    2243           0 :   Node* check = __ Uint64LessThanOrEqual(value, __ Int64Constant(kMaxInt));
    2244             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2245           0 :                      frame_state);
    2246           0 :   return __ TruncateInt64ToInt32(value);
    2247             : }
    2248             : 
    2249           0 : Node* EffectControlLinearizer::LowerCheckedUint64ToTaggedSigned(
    2250             :     Node* node, Node* frame_state) {
    2251             :   Node* value = node->InputAt(0);
    2252           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2253             : 
    2254             :   Node* check =
    2255           0 :       __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
    2256             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
    2257           0 :                      frame_state);
    2258           0 :   return ChangeInt64ToSmi(value);
    2259             : }
    2260             : 
    2261        4627 : Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
    2262             :     CheckForMinusZeroMode mode, const VectorSlotPair& feedback, Node* value,
    2263             :     Node* frame_state) {
    2264        4627 :   Node* value32 = __ RoundFloat64ToInt32(value);
    2265        4627 :   Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
    2266             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
    2267        4627 :                      check_same, frame_state);
    2268             : 
    2269        4627 :   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
    2270             :     // Check if {value} is -0.
    2271        2156 :     auto if_zero = __ MakeDeferredLabel();
    2272        2156 :     auto check_done = __ MakeLabel();
    2273             : 
    2274        2156 :     Node* check_zero = __ Word32Equal(value32, __ Int32Constant(0));
    2275        2156 :     __ GotoIf(check_zero, &if_zero);
    2276             :     __ Goto(&check_done);
    2277             : 
    2278             :     __ Bind(&if_zero);
    2279             :     // In case of 0, we need to check the high bits for the IEEE -0 pattern.
    2280        2156 :     Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
    2281        2156 :                                             __ Int32Constant(0));
    2282             :     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative,
    2283        2156 :                     frame_state);
    2284             :     __ Goto(&check_done);
    2285             : 
    2286             :     __ Bind(&check_done);
    2287             :   }
    2288        4627 :   return value32;
    2289             : }
    2290             : 
    2291        2315 : Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
    2292             :                                                           Node* frame_state) {
    2293             :   const CheckMinusZeroParameters& params =
    2294        2315 :       CheckMinusZeroParametersOf(node->op());
    2295             :   Node* value = node->InputAt(0);
    2296             :   return BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), value,
    2297        2315 :                                     frame_state);
    2298             : }
    2299             : 
    2300         103 : Node* EffectControlLinearizer::BuildCheckedFloat64ToInt64(
    2301             :     CheckForMinusZeroMode mode, const VectorSlotPair& feedback, Node* value,
    2302             :     Node* frame_state) {
    2303         103 :   Node* value64 = __ TruncateFloat64ToInt64(value);
    2304         103 :   Node* check_same = __ Float64Equal(value, __ ChangeInt64ToFloat64(value64));
    2305             :   __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
    2306         103 :                      check_same, frame_state);
    2307             : 
    2308         103 :   if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
    2309             :     // Check if {value} is -0.
    2310           0 :     auto if_zero = __ MakeDeferredLabel();
    2311           0 :     auto check_done = __ MakeLabel();
    2312             : 
    2313           0 :     Node* check_zero = __ Word64Equal(value64, __ Int64Constant(0));
    2314           0 :     __ GotoIf(check_zero, &if_zero);
    2315             :     __ Goto(&check_done);
    2316             : 
    2317             :     __ Bind(&if_zero);
    2318             :     // In case of 0, we need to check the high bits for the IEEE -0 pattern.
    2319           0 :     Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
    2320           0 :                                             __ Int32Constant(0));
    2321             :     __ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative,
    2322           0 :                     frame_state);
    2323             :     __ Goto(&check_done);
    2324             : 
    2325             :     __ Bind(&check_done);
    2326             :   }
    2327         103 :   return value64;
    2328             : }
    2329             : 
    2330          16 : Node* EffectControlLinearizer::LowerCheckedFloat64ToInt64(Node* node,
    2331             :                                                           Node* frame_state) {
    2332             :   const CheckMinusZeroParameters& params =
    2333          16 :       CheckMinusZeroParametersOf(node->op());
    2334             :   Node* value = node->InputAt(0);
    2335             :   return BuildCheckedFloat64ToInt64(params.mode(), params.feedback(), value,
    2336          16 :                                     frame_state);
    2337             : }
    2338             : 
    2339       24758 : Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(
    2340             :     Node* node, Node* frame_state) {
    2341             :   Node* value = node->InputAt(0);
    2342       24758 :   const CheckParameters& params = CheckParametersOf(node->op());
    2343       24759 :   Node* check = ObjectIsSmi(value);
    2344             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
    2345       24759 :                      frame_state);
    2346       24758 :   return ChangeSmiToInt32(value);
    2347             : }
    2348             : 
    2349        2312 : Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
    2350             :                                                          Node* frame_state) {
    2351             :   const CheckMinusZeroParameters& params =
    2352        2312 :       CheckMinusZeroParametersOf(node->op());
    2353             :   Node* value = node->InputAt(0);
    2354             : 
    2355        2312 :   auto if_not_smi = __ MakeDeferredLabel();
    2356        4624 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    2357             : 
    2358        2312 :   Node* check = ObjectIsSmi(value);
    2359        2312 :   __ GotoIfNot(check, &if_not_smi);
    2360             :   // In the Smi case, just convert to int32.
    2361        2312 :   __ Goto(&done, ChangeSmiToInt32(value));
    2362             : 
    2363             :   // In the non-Smi case, check the heap numberness, load the number and convert
    2364             :   // to int32.
    2365             :   __ Bind(&if_not_smi);
    2366        2312 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2367        2312 :   Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant());
    2368             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
    2369        2312 :                      check_map, frame_state);
    2370        2312 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2371             :   vfalse = BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), vfalse,
    2372        2312 :                                       frame_state);
    2373             :   __ Goto(&done, vfalse);
    2374             : 
    2375             :   __ Bind(&done);
    2376        2312 :   return done.PhiAt(0);
    2377             : }
    2378             : 
    2379          87 : Node* EffectControlLinearizer::LowerCheckedTaggedToInt64(Node* node,
    2380             :                                                          Node* frame_state) {
    2381             :   const CheckMinusZeroParameters& params =
    2382          87 :       CheckMinusZeroParametersOf(node->op());
    2383             :   Node* value = node->InputAt(0);
    2384             : 
    2385          87 :   auto if_not_smi = __ MakeDeferredLabel();
    2386         174 :   auto done = __ MakeLabel(MachineRepresentation::kWord64);
    2387             : 
    2388          87 :   Node* check = ObjectIsSmi(value);
    2389          87 :   __ GotoIfNot(check, &if_not_smi);
    2390             :   // In the Smi case, just convert to int64.
    2391          87 :   __ Goto(&done, ChangeSmiToInt64(value));
    2392             : 
    2393             :   // In the non-Smi case, check the heap numberness, load the number and convert
    2394             :   // to int64.
    2395             :   __ Bind(&if_not_smi);
    2396          87 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2397          87 :   Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant());
    2398             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
    2399          87 :                      check_map, frame_state);
    2400          87 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2401             :   vfalse = BuildCheckedFloat64ToInt64(params.mode(), params.feedback(), vfalse,
    2402          87 :                                       frame_state);
    2403             :   __ Goto(&done, vfalse);
    2404             : 
    2405             :   __ Bind(&done);
    2406          87 :   return done.PhiAt(0);
    2407             : }
    2408             : 
    2409       52308 : Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
    2410             :     CheckTaggedInputMode mode, const VectorSlotPair& feedback, Node* value,
    2411             :     Node* frame_state) {
    2412      104616 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2413       52308 :   Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant());
    2414       52308 :   switch (mode) {
    2415             :     case CheckTaggedInputMode::kNumber: {
    2416             :       __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, feedback,
    2417        8299 :                          check_number, frame_state);
    2418        8299 :       break;
    2419             :     }
    2420             :     case CheckTaggedInputMode::kNumberOrOddball: {
    2421       44009 :       auto check_done = __ MakeLabel();
    2422             : 
    2423       44009 :       __ GotoIf(check_number, &check_done);
    2424             :       // For oddballs also contain the numeric value, let us just check that
    2425             :       // we have an oddball here.
    2426             :       Node* instance_type =
    2427       44009 :           __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    2428             :       Node* check_oddball =
    2429       44009 :           __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE));
    2430             :       __ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball, feedback,
    2431       44009 :                          check_oddball, frame_state);
    2432             :       STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    2433             :                                         Oddball::kToNumberRawOffset);
    2434             :       __ Goto(&check_done);
    2435             : 
    2436             :       __ Bind(&check_done);
    2437             :       break;
    2438             :     }
    2439             :   }
    2440       52308 :   return __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2441             : }
    2442             : 
    2443       51131 : Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
    2444             :                                                            Node* frame_state) {
    2445             :   CheckTaggedInputParameters const& p =
    2446       51131 :       CheckTaggedInputParametersOf(node->op());
    2447             :   Node* value = node->InputAt(0);
    2448             : 
    2449       51131 :   auto if_smi = __ MakeLabel();
    2450      102262 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    2451             : 
    2452       51131 :   Node* check = ObjectIsSmi(value);
    2453       51131 :   __ GotoIf(check, &if_smi);
    2454             : 
    2455             :   // In the Smi case, just convert to int32 and then float64.
    2456             :   // Otherwise, check heap numberness and load the number.
    2457             :   Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
    2458       51131 :       p.mode(), p.feedback(), value, frame_state);
    2459             :   __ Goto(&done, number);
    2460             : 
    2461             :   __ Bind(&if_smi);
    2462       51131 :   Node* from_smi = ChangeSmiToInt32(value);
    2463       51131 :   from_smi = __ ChangeInt32ToFloat64(from_smi);
    2464             :   __ Goto(&done, from_smi);
    2465             : 
    2466             :   __ Bind(&done);
    2467       51131 :   return done.PhiAt(0);
    2468             : }
    2469             : 
    2470       18852 : Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
    2471             :     Node* node, Node* frame_state) {
    2472             :   Node* value = node->InputAt(0);
    2473       18852 :   const CheckParameters& params = CheckParametersOf(node->op());
    2474             : 
    2475       18852 :   Node* check = ObjectIsSmi(value);
    2476             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
    2477       18852 :                      frame_state);
    2478             : 
    2479       18852 :   return value;
    2480             : }
    2481             : 
    2482       34469 : Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(
    2483             :     Node* node, Node* frame_state) {
    2484             :   Node* value = node->InputAt(0);
    2485       34469 :   const CheckParameters& params = CheckParametersOf(node->op());
    2486             : 
    2487       34469 :   Node* check = ObjectIsSmi(value);
    2488             :   __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check,
    2489       34469 :                   frame_state);
    2490       34469 :   return value;
    2491             : }
    2492             : 
    2493           0 : Node* EffectControlLinearizer::LowerCheckedCompressedToTaggedSigned(
    2494             :     Node* node, Node* frame_state) {
    2495             :   Node* value = node->InputAt(0);
    2496           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2497             : 
    2498           0 :   Node* check = ObjectIsSmi(value);
    2499             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
    2500           0 :                      frame_state);
    2501             : 
    2502           0 :   return __ ChangeCompressedSignedToTaggedSigned(value);
    2503             : }
    2504             : 
    2505           0 : Node* EffectControlLinearizer::LowerCheckedCompressedToTaggedPointer(
    2506             :     Node* node, Node* frame_state) {
    2507             :   Node* value = node->InputAt(0);
    2508           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2509             : 
    2510           0 :   Node* check = ObjectIsSmi(value);
    2511             :   __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check,
    2512           0 :                   frame_state);
    2513           0 :   return __ ChangeCompressedPointerToTaggedPointer(value);
    2514             : }
    2515             : 
    2516           0 : Node* EffectControlLinearizer::LowerCheckedTaggedToCompressedSigned(
    2517             :     Node* node, Node* frame_state) {
    2518             :   Node* value = node->InputAt(0);
    2519           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2520             : 
    2521           0 :   Node* check = ObjectIsSmi(value);
    2522             :   __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
    2523           0 :                      frame_state);
    2524             : 
    2525           0 :   return __ ChangeTaggedSignedToCompressedSigned(value);
    2526             : }
    2527             : 
    2528           0 : Node* EffectControlLinearizer::LowerCheckedTaggedToCompressedPointer(
    2529             :     Node* node, Node* frame_state) {
    2530             :   Node* value = node->InputAt(0);
    2531           0 :   const CheckParameters& params = CheckParametersOf(node->op());
    2532             : 
    2533           0 :   Node* check = ObjectIsSmi(value);
    2534             :   __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check,
    2535           0 :                   frame_state);
    2536           0 :   return __ ChangeTaggedPointerToCompressedPointer(value);
    2537             : }
    2538             : 
    2539         501 : Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) {
    2540             :   Node* value = node->InputAt(0);
    2541             : 
    2542         501 :   auto if_not_smi = __ MakeDeferredLabel();
    2543        1002 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    2544             : 
    2545         501 :   Node* check = ObjectIsSmi(value);
    2546         501 :   __ GotoIfNot(check, &if_not_smi);
    2547         501 :   __ Goto(&done, ChangeSmiToInt32(value));
    2548             : 
    2549             :   __ Bind(&if_not_smi);
    2550             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    2551             :                                     Oddball::kToNumberRawOffset);
    2552         501 :   Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2553         501 :   vfalse = __ TruncateFloat64ToWord32(vfalse);
    2554             :   __ Goto(&done, vfalse);
    2555             : 
    2556             :   __ Bind(&done);
    2557         501 :   return done.PhiAt(0);
    2558             : }
    2559             : 
    2560        1177 : Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
    2561             :     Node* node, Node* frame_state) {
    2562             :   const CheckTaggedInputParameters& params =
    2563        1177 :       CheckTaggedInputParametersOf(node->op());
    2564             :   Node* value = node->InputAt(0);
    2565             : 
    2566        1177 :   auto if_not_smi = __ MakeLabel();
    2567        2354 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    2568             : 
    2569        1177 :   Node* check = ObjectIsSmi(value);
    2570        1177 :   __ GotoIfNot(check, &if_not_smi);
    2571             :   // In the Smi case, just convert to int32.
    2572        1177 :   __ Goto(&done, ChangeSmiToInt32(value));
    2573             : 
    2574             :   // Otherwise, check that it's a heap number or oddball and truncate the value
    2575             :   // to int32.
    2576             :   __ Bind(&if_not_smi);
    2577             :   Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
    2578        1177 :       params.mode(), params.feedback(), value, frame_state);
    2579        1177 :   number = __ TruncateFloat64ToWord32(number);
    2580             :   __ Goto(&done, number);
    2581             : 
    2582             :   __ Bind(&done);
    2583        1177 :   return done.PhiAt(0);
    2584             : }
    2585             : 
    2586      112778 : Node* EffectControlLinearizer::LowerAllocate(Node* node) {
    2587             :   Node* size = node->InputAt(0);
    2588      112778 :   AllocationType allocation = AllocationTypeOf(node->op());
    2589      112778 :   Node* new_node = __ Allocate(allocation, size);
    2590      112778 :   return new_node;
    2591             : }
    2592             : 
    2593         993 : Node* EffectControlLinearizer::LowerNumberToString(Node* node) {
    2594             :   Node* argument = node->InputAt(0);
    2595             : 
    2596             :   Callable const callable =
    2597         993 :       Builtins::CallableFor(isolate(), Builtins::kNumberToString);
    2598             :   Operator::Properties properties = Operator::kEliminatable;
    2599             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    2600             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    2601         993 :       graph()->zone(), callable.descriptor(),
    2602         993 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    2603        2979 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), argument,
    2604        1986 :                  __ NoContextConstant());
    2605             : }
    2606             : 
    2607          16 : Node* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) {
    2608             :   Node* value = node->InputAt(0);
    2609             : 
    2610          16 :   auto if_smi = __ MakeDeferredLabel();
    2611          32 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2612             : 
    2613          16 :   Node* check = ObjectIsSmi(value);
    2614          16 :   __ GotoIf(check, &if_smi);
    2615             : 
    2616          16 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2617             :   Node* value_instance_type =
    2618          16 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    2619             :   STATIC_ASSERT(JS_TYPED_ARRAY_TYPE + 1 == JS_DATA_VIEW_TYPE);
    2620          16 :   Node* vfalse = __ Uint32LessThan(
    2621             :       __ Int32Sub(value_instance_type, __ Int32Constant(JS_TYPED_ARRAY_TYPE)),
    2622          16 :       __ Int32Constant(2));
    2623             :   __ Goto(&done, vfalse);
    2624             : 
    2625             :   __ Bind(&if_smi);
    2626          16 :   __ Goto(&done, __ Int32Constant(0));
    2627             : 
    2628             :   __ Bind(&done);
    2629          16 :   return done.PhiAt(0);
    2630             : }
    2631             : 
    2632          25 : Node* EffectControlLinearizer::LowerObjectIsBigInt(Node* node) {
    2633             :   Node* value = node->InputAt(0);
    2634             : 
    2635          25 :   auto if_smi = __ MakeDeferredLabel();
    2636          50 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2637             : 
    2638          25 :   Node* check = ObjectIsSmi(value);
    2639          25 :   __ GotoIf(check, &if_smi);
    2640          25 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2641          25 :   Node* vfalse = __ WordEqual(value_map, __ BigIntMapConstant());
    2642             :   __ Goto(&done, vfalse);
    2643             : 
    2644             :   __ Bind(&if_smi);
    2645          25 :   __ Goto(&done, __ Int32Constant(0));
    2646             : 
    2647             :   __ Bind(&done);
    2648          25 :   return done.PhiAt(0);
    2649             : }
    2650             : 
    2651         104 : Node* EffectControlLinearizer::LowerObjectIsCallable(Node* node) {
    2652             :   Node* value = node->InputAt(0);
    2653             : 
    2654         104 :   auto if_smi = __ MakeDeferredLabel();
    2655         208 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2656             : 
    2657         104 :   Node* check = ObjectIsSmi(value);
    2658         104 :   __ GotoIf(check, &if_smi);
    2659             : 
    2660         104 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2661             :   Node* value_bit_field =
    2662         104 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    2663             :   Node* vfalse =
    2664         104 :       __ Word32Equal(__ Int32Constant(Map::IsCallableBit::kMask),
    2665             :                      __ Word32And(value_bit_field,
    2666         104 :                                   __ Int32Constant(Map::IsCallableBit::kMask)));
    2667             :   __ Goto(&done, vfalse);
    2668             : 
    2669             :   __ Bind(&if_smi);
    2670         104 :   __ Goto(&done, __ Int32Constant(0));
    2671             : 
    2672             :   __ Bind(&done);
    2673         104 :   return done.PhiAt(0);
    2674             : }
    2675             : 
    2676         379 : Node* EffectControlLinearizer::LowerObjectIsConstructor(Node* node) {
    2677             :   Node* value = node->InputAt(0);
    2678             : 
    2679         379 :   auto if_smi = __ MakeDeferredLabel();
    2680         758 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2681             : 
    2682         379 :   Node* check = ObjectIsSmi(value);
    2683         379 :   __ GotoIf(check, &if_smi);
    2684             : 
    2685         379 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2686             :   Node* value_bit_field =
    2687         379 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    2688         379 :   Node* vfalse = __ Word32Equal(
    2689             :       __ Int32Constant(Map::IsConstructorBit::kMask),
    2690             :       __ Word32And(value_bit_field,
    2691         379 :                    __ Int32Constant(Map::IsConstructorBit::kMask)));
    2692             :   __ Goto(&done, vfalse);
    2693             : 
    2694             :   __ Bind(&if_smi);
    2695         379 :   __ Goto(&done, __ Int32Constant(0));
    2696             : 
    2697             :   __ Bind(&done);
    2698         379 :   return done.PhiAt(0);
    2699             : }
    2700             : 
    2701       14119 : Node* EffectControlLinearizer::LowerObjectIsDetectableCallable(Node* node) {
    2702             :   Node* value = node->InputAt(0);
    2703             : 
    2704       14119 :   auto if_smi = __ MakeDeferredLabel();
    2705       28238 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2706             : 
    2707       14119 :   Node* check = ObjectIsSmi(value);
    2708       14119 :   __ GotoIf(check, &if_smi);
    2709             : 
    2710       14119 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2711             :   Node* value_bit_field =
    2712       14119 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    2713       14119 :   Node* vfalse = __ Word32Equal(
    2714             :       __ Int32Constant(Map::IsCallableBit::kMask),
    2715             :       __ Word32And(value_bit_field,
    2716             :                    __ Int32Constant((Map::IsCallableBit::kMask) |
    2717       14119 :                                     (Map::IsUndetectableBit::kMask))));
    2718             :   __ Goto(&done, vfalse);
    2719             : 
    2720             :   __ Bind(&if_smi);
    2721       14119 :   __ Goto(&done, __ Int32Constant(0));
    2722             : 
    2723             :   __ Bind(&done);
    2724       14119 :   return done.PhiAt(0);
    2725             : }
    2726             : 
    2727          61 : Node* EffectControlLinearizer::LowerNumberIsFloat64Hole(Node* node) {
    2728             :   Node* value = node->InputAt(0);
    2729          61 :   Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
    2730          61 :                                __ Int32Constant(kHoleNanUpper32));
    2731          61 :   return check;
    2732             : }
    2733             : 
    2734         126 : Node* EffectControlLinearizer::LowerNumberIsFinite(Node* node) {
    2735             :   Node* number = node->InputAt(0);
    2736         126 :   Node* diff = __ Float64Sub(number, number);
    2737         126 :   Node* check = __ Float64Equal(diff, diff);
    2738         126 :   return check;
    2739             : }
    2740             : 
    2741           7 : Node* EffectControlLinearizer::LowerObjectIsFiniteNumber(Node* node) {
    2742             :   Node* object = node->InputAt(0);
    2743           7 :   Node* zero = __ Int32Constant(0);
    2744           7 :   Node* one = __ Int32Constant(1);
    2745             : 
    2746          14 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2747             : 
    2748             :   // Check if {object} is a Smi.
    2749           7 :   __ GotoIf(ObjectIsSmi(object), &done, one);
    2750             : 
    2751             :   // Check if {object} is a HeapNumber.
    2752           7 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
    2753           7 :   __ GotoIfNot(__ WordEqual(value_map, __ HeapNumberMapConstant()), &done,
    2754           7 :                zero);
    2755             : 
    2756             :   // {object} is a HeapNumber.
    2757           7 :   Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
    2758           7 :   Node* diff = __ Float64Sub(value, value);
    2759           7 :   Node* check = __ Float64Equal(diff, diff);
    2760             :   __ Goto(&done, check);
    2761             : 
    2762             :   __ Bind(&done);
    2763           7 :   return done.PhiAt(0);
    2764             : }
    2765             : 
    2766         119 : Node* EffectControlLinearizer::LowerNumberIsInteger(Node* node) {
    2767             :   Node* number = node->InputAt(0);
    2768         119 :   Node* trunc = BuildFloat64RoundTruncate(number);
    2769         119 :   Node* diff = __ Float64Sub(number, trunc);
    2770         119 :   Node* check = __ Float64Equal(diff, __ Float64Constant(0));
    2771         119 :   return check;
    2772             : }
    2773             : 
    2774           7 : Node* EffectControlLinearizer::LowerObjectIsInteger(Node* node) {
    2775             :   Node* object = node->InputAt(0);
    2776           7 :   Node* zero = __ Int32Constant(0);
    2777           7 :   Node* one = __ Int32Constant(1);
    2778             : 
    2779          14 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2780             : 
    2781             :   // Check if {object} is a Smi.
    2782           7 :   __ GotoIf(ObjectIsSmi(object), &done, one);
    2783             : 
    2784             :   // Check if {object} is a HeapNumber.
    2785           7 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
    2786           7 :   __ GotoIfNot(__ WordEqual(value_map, __ HeapNumberMapConstant()), &done,
    2787           7 :                zero);
    2788             : 
    2789             :   // {object} is a HeapNumber.
    2790           7 :   Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
    2791           7 :   Node* trunc = BuildFloat64RoundTruncate(value);
    2792           7 :   Node* diff = __ Float64Sub(value, trunc);
    2793           7 :   Node* check = __ Float64Equal(diff, __ Float64Constant(0));
    2794             :   __ Goto(&done, check);
    2795             : 
    2796             :   __ Bind(&done);
    2797           7 :   return done.PhiAt(0);
    2798             : }
    2799             : 
    2800           7 : Node* EffectControlLinearizer::LowerNumberIsSafeInteger(Node* node) {
    2801             :   Node* number = node->InputAt(0);
    2802           7 :   Node* zero = __ Int32Constant(0);
    2803          14 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2804             : 
    2805           7 :   Node* trunc = BuildFloat64RoundTruncate(number);
    2806           7 :   Node* diff = __ Float64Sub(number, trunc);
    2807           7 :   Node* check = __ Float64Equal(diff, __ Float64Constant(0));
    2808           7 :   __ GotoIfNot(check, &done, zero);
    2809           7 :   Node* in_range = __ Float64LessThanOrEqual(
    2810           7 :       __ Float64Abs(trunc), __ Float64Constant(kMaxSafeInteger));
    2811             :   __ Goto(&done, in_range);
    2812             : 
    2813             :   __ Bind(&done);
    2814           7 :   return done.PhiAt(0);
    2815             : }
    2816             : 
    2817           7 : Node* EffectControlLinearizer::LowerObjectIsSafeInteger(Node* node) {
    2818             :   Node* object = node->InputAt(0);
    2819           7 :   Node* zero = __ Int32Constant(0);
    2820           7 :   Node* one = __ Int32Constant(1);
    2821             : 
    2822          14 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2823             : 
    2824             :   // Check if {object} is a Smi.
    2825           7 :   __ GotoIf(ObjectIsSmi(object), &done, one);
    2826             : 
    2827             :   // Check if {object} is a HeapNumber.
    2828           7 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), object);
    2829           7 :   __ GotoIfNot(__ WordEqual(value_map, __ HeapNumberMapConstant()), &done,
    2830           7 :                zero);
    2831             : 
    2832             :   // {object} is a HeapNumber.
    2833           7 :   Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), object);
    2834           7 :   Node* trunc = BuildFloat64RoundTruncate(value);
    2835           7 :   Node* diff = __ Float64Sub(value, trunc);
    2836           7 :   Node* check = __ Float64Equal(diff, __ Float64Constant(0));
    2837           7 :   __ GotoIfNot(check, &done, zero);
    2838           7 :   Node* in_range = __ Float64LessThanOrEqual(
    2839           7 :       __ Float64Abs(trunc), __ Float64Constant(kMaxSafeInteger));
    2840             :   __ Goto(&done, in_range);
    2841             : 
    2842             :   __ Bind(&done);
    2843           7 :   return done.PhiAt(0);
    2844             : }
    2845             : 
    2846             : namespace {
    2847             : 
    2848       61018 : const int64_t kMinusZeroBits = bit_cast<int64_t>(-0.0);
    2849       61018 : const int32_t kMinusZeroLoBits = static_cast<int32_t>(kMinusZeroBits);
    2850       61018 : const int32_t kMinusZeroHiBits = static_cast<int32_t>(kMinusZeroBits >> 32);
    2851             : 
    2852             : }  // namespace
    2853             : 
    2854          23 : Node* EffectControlLinearizer::LowerObjectIsMinusZero(Node* node) {
    2855             :   Node* value = node->InputAt(0);
    2856          23 :   Node* zero = __ Int32Constant(0);
    2857             : 
    2858          46 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2859             : 
    2860             :   // Check if {value} is a Smi.
    2861          23 :   __ GotoIf(ObjectIsSmi(value), &done, zero);
    2862             : 
    2863             :   // Check if {value} is a HeapNumber.
    2864          23 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2865          23 :   __ GotoIfNot(__ WordEqual(value_map, __ HeapNumberMapConstant()), &done,
    2866          23 :                zero);
    2867             : 
    2868             :   // Check if {value} contains -0.
    2869          23 :   Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2870          23 :   if (machine()->Is64()) {
    2871          23 :     Node* value64 = __ BitcastFloat64ToInt64(value_value);
    2872          23 :     __ Goto(&done, __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits)));
    2873             :   } else {
    2874           0 :     Node* value_lo = __ Float64ExtractLowWord32(value_value);
    2875           0 :     __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
    2876           0 :                  &done, zero);
    2877           0 :     Node* value_hi = __ Float64ExtractHighWord32(value_value);
    2878           0 :     __ Goto(&done,
    2879             :             __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
    2880             :   }
    2881             : 
    2882             :   __ Bind(&done);
    2883          23 :   return done.PhiAt(0);
    2884             : }
    2885             : 
    2886          98 : Node* EffectControlLinearizer::LowerNumberIsMinusZero(Node* node) {
    2887             :   Node* value = node->InputAt(0);
    2888             : 
    2889          98 :   if (machine()->Is64()) {
    2890          98 :     Node* value64 = __ BitcastFloat64ToInt64(value);
    2891          98 :     return __ Word64Equal(value64, __ Int64Constant(kMinusZeroBits));
    2892             :   } else {
    2893           0 :     auto done = __ MakeLabel(MachineRepresentation::kBit);
    2894             : 
    2895           0 :     Node* value_lo = __ Float64ExtractLowWord32(value);
    2896           0 :     __ GotoIfNot(__ Word32Equal(value_lo, __ Int32Constant(kMinusZeroLoBits)),
    2897           0 :                  &done, __ Int32Constant(0));
    2898           0 :     Node* value_hi = __ Float64ExtractHighWord32(value);
    2899           0 :     __ Goto(&done,
    2900             :             __ Word32Equal(value_hi, __ Int32Constant(kMinusZeroHiBits)));
    2901             : 
    2902             :     __ Bind(&done);
    2903             :     return done.PhiAt(0);
    2904             :   }
    2905             : }
    2906             : 
    2907         716 : Node* EffectControlLinearizer::LowerObjectIsNaN(Node* node) {
    2908             :   Node* value = node->InputAt(0);
    2909         716 :   Node* zero = __ Int32Constant(0);
    2910             : 
    2911        1432 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2912             : 
    2913             :   // Check if {value} is a Smi.
    2914         716 :   __ GotoIf(ObjectIsSmi(value), &done, zero);
    2915             : 
    2916             :   // Check if {value} is a HeapNumber.
    2917         716 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2918         716 :   __ GotoIfNot(__ WordEqual(value_map, __ HeapNumberMapConstant()), &done,
    2919         716 :                zero);
    2920             : 
    2921             :   // Check if {value} contains a NaN.
    2922         716 :   Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    2923         716 :   __ Goto(&done,
    2924             :           __ Word32Equal(__ Float64Equal(value_value, value_value), zero));
    2925             : 
    2926             :   __ Bind(&done);
    2927         716 :   return done.PhiAt(0);
    2928             : }
    2929             : 
    2930        2516 : Node* EffectControlLinearizer::LowerNumberIsNaN(Node* node) {
    2931             :   Node* number = node->InputAt(0);
    2932        2516 :   Node* diff = __ Float64Equal(number, number);
    2933        2516 :   Node* check = __ Word32Equal(diff, __ Int32Constant(0));
    2934        2516 :   return check;
    2935             : }
    2936             : 
    2937        6060 : Node* EffectControlLinearizer::LowerObjectIsNonCallable(Node* node) {
    2938             :   Node* value = node->InputAt(0);
    2939             : 
    2940        6060 :   auto if_primitive = __ MakeDeferredLabel();
    2941       12120 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2942             : 
    2943        6060 :   Node* check0 = ObjectIsSmi(value);
    2944        6060 :   __ GotoIf(check0, &if_primitive);
    2945             : 
    2946        6060 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2947             :   Node* value_instance_type =
    2948        6060 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    2949             :   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    2950        6060 :   Node* check1 = __ Uint32LessThanOrEqual(
    2951        6060 :       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
    2952        6060 :   __ GotoIfNot(check1, &if_primitive);
    2953             : 
    2954             :   Node* value_bit_field =
    2955        6060 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    2956             :   Node* check2 =
    2957        6060 :       __ Word32Equal(__ Int32Constant(0),
    2958             :                      __ Word32And(value_bit_field,
    2959        6060 :                                   __ Int32Constant(Map::IsCallableBit::kMask)));
    2960             :   __ Goto(&done, check2);
    2961             : 
    2962             :   __ Bind(&if_primitive);
    2963        6060 :   __ Goto(&done, __ Int32Constant(0));
    2964             : 
    2965             :   __ Bind(&done);
    2966        6060 :   return done.PhiAt(0);
    2967             : }
    2968             : 
    2969        7582 : Node* EffectControlLinearizer::LowerObjectIsNumber(Node* node) {
    2970             :   Node* value = node->InputAt(0);
    2971             : 
    2972        7582 :   auto if_smi = __ MakeLabel();
    2973       15164 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2974             : 
    2975       15164 :   __ GotoIf(ObjectIsSmi(value), &if_smi);
    2976        7582 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2977        7582 :   __ Goto(&done, __ WordEqual(value_map, __ HeapNumberMapConstant()));
    2978             : 
    2979             :   __ Bind(&if_smi);
    2980        7582 :   __ Goto(&done, __ Int32Constant(1));
    2981             : 
    2982             :   __ Bind(&done);
    2983        7582 :   return done.PhiAt(0);
    2984             : }
    2985             : 
    2986       19606 : Node* EffectControlLinearizer::LowerObjectIsReceiver(Node* node) {
    2987             :   Node* value = node->InputAt(0);
    2988             : 
    2989       19606 :   auto if_smi = __ MakeDeferredLabel();
    2990       39212 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    2991             : 
    2992       39212 :   __ GotoIf(ObjectIsSmi(value), &if_smi);
    2993             : 
    2994             :   STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    2995       19606 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    2996             :   Node* value_instance_type =
    2997       19606 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    2998       19606 :   Node* result = __ Uint32LessThanOrEqual(
    2999       19606 :       __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type);
    3000             :   __ Goto(&done, result);
    3001             : 
    3002             :   __ Bind(&if_smi);
    3003       19606 :   __ Goto(&done, __ Int32Constant(0));
    3004             : 
    3005             :   __ Bind(&done);
    3006       19606 :   return done.PhiAt(0);
    3007             : }
    3008             : 
    3009        4130 : Node* EffectControlLinearizer::LowerObjectIsSmi(Node* node) {
    3010             :   Node* value = node->InputAt(0);
    3011        4130 :   return ObjectIsSmi(value);
    3012             : }
    3013             : 
    3014        2223 : Node* EffectControlLinearizer::LowerObjectIsString(Node* node) {
    3015             :   Node* value = node->InputAt(0);
    3016             : 
    3017        2223 :   auto if_smi = __ MakeDeferredLabel();
    3018        4446 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    3019             : 
    3020        2223 :   Node* check = ObjectIsSmi(value);
    3021        2223 :   __ GotoIf(check, &if_smi);
    3022        2223 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    3023             :   Node* value_instance_type =
    3024        2223 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    3025        2223 :   Node* vfalse = __ Uint32LessThan(value_instance_type,
    3026        2223 :                                    __ Uint32Constant(FIRST_NONSTRING_TYPE));
    3027             :   __ Goto(&done, vfalse);
    3028             : 
    3029             :   __ Bind(&if_smi);
    3030        2223 :   __ Goto(&done, __ Int32Constant(0));
    3031             : 
    3032             :   __ Bind(&done);
    3033        2223 :   return done.PhiAt(0);
    3034             : }
    3035             : 
    3036          23 : Node* EffectControlLinearizer::LowerObjectIsSymbol(Node* node) {
    3037             :   Node* value = node->InputAt(0);
    3038             : 
    3039          23 :   auto if_smi = __ MakeDeferredLabel();
    3040          46 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    3041             : 
    3042          23 :   Node* check = ObjectIsSmi(value);
    3043          23 :   __ GotoIf(check, &if_smi);
    3044          23 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    3045             :   Node* value_instance_type =
    3046          23 :       __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    3047             :   Node* vfalse =
    3048          23 :       __ Word32Equal(value_instance_type, __ Uint32Constant(SYMBOL_TYPE));
    3049             :   __ Goto(&done, vfalse);
    3050             : 
    3051             :   __ Bind(&if_smi);
    3052          23 :   __ Goto(&done, __ Int32Constant(0));
    3053             : 
    3054             :   __ Bind(&done);
    3055          23 :   return done.PhiAt(0);
    3056             : }
    3057             : 
    3058        1425 : Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) {
    3059             :   Node* value = node->InputAt(0);
    3060             : 
    3061        1425 :   auto if_smi = __ MakeDeferredLabel();
    3062        2850 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    3063             : 
    3064        1425 :   Node* check = ObjectIsSmi(value);
    3065        1425 :   __ GotoIf(check, &if_smi);
    3066             : 
    3067        1425 :   Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    3068             :   Node* value_bit_field =
    3069        1425 :       __ LoadField(AccessBuilder::ForMapBitField(), value_map);
    3070        1425 :   Node* vfalse = __ Word32Equal(
    3071             :       __ Word32Equal(
    3072             :           __ Int32Constant(0),
    3073             :           __ Word32And(value_bit_field,
    3074             :                        __ Int32Constant(Map::IsUndetectableBit::kMask))),
    3075        1425 :       __ Int32Constant(0));
    3076             :   __ Goto(&done, vfalse);
    3077             : 
    3078             :   __ Bind(&if_smi);
    3079        1425 :   __ Goto(&done, __ Int32Constant(0));
    3080             : 
    3081             :   __ Bind(&done);
    3082        1425 :   return done.PhiAt(0);
    3083             : }
    3084             : 
    3085       21373 : Node* EffectControlLinearizer::LowerTypeOf(Node* node) {
    3086             :   Node* obj = node->InputAt(0);
    3087       21373 :   Callable const callable = Builtins::CallableFor(isolate(), Builtins::kTypeof);
    3088             :   Operator::Properties const properties = Operator::kEliminatable;
    3089             :   CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
    3090             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3091       21373 :       graph()->zone(), callable.descriptor(),
    3092       21373 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3093       64119 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj,
    3094       42746 :                  __ NoContextConstant());
    3095             : }
    3096             : 
    3097         200 : Node* EffectControlLinearizer::LowerToBoolean(Node* node) {
    3098             :   Node* obj = node->InputAt(0);
    3099             :   Callable const callable =
    3100         200 :       Builtins::CallableFor(isolate(), Builtins::kToBoolean);
    3101             :   Operator::Properties const properties = Operator::kEliminatable;
    3102             :   CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
    3103             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3104         200 :       graph()->zone(), callable.descriptor(),
    3105         200 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3106         600 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj,
    3107         400 :                  __ NoContextConstant());
    3108             : }
    3109             : 
    3110       16941 : Node* EffectControlLinearizer::LowerArgumentsLength(Node* node) {
    3111       16941 :   Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
    3112       16941 :   int formal_parameter_count = FormalParameterCountOf(node->op());
    3113       16941 :   bool is_rest_length = IsRestLengthOf(node->op());
    3114             :   DCHECK_LE(0, formal_parameter_count);
    3115             : 
    3116       16941 :   if (is_rest_length) {
    3117             :     // The ArgumentsLength node is computing the number of rest parameters,
    3118             :     // which is max(0, actual_parameter_count - formal_parameter_count).
    3119             :     // We have to distinguish the case, when there is an arguments adaptor frame
    3120             :     // (i.e., arguments_frame != LoadFramePointer()).
    3121         229 :     auto if_adaptor_frame = __ MakeLabel();
    3122         458 :     auto done = __ MakeLabel(MachineRepresentation::kTaggedSigned);
    3123             : 
    3124         229 :     Node* frame = __ LoadFramePointer();
    3125         229 :     __ GotoIf(__ WordEqual(arguments_frame, frame), &done, __ SmiConstant(0));
    3126             :     __ Goto(&if_adaptor_frame);
    3127             : 
    3128             :     __ Bind(&if_adaptor_frame);
    3129         229 :     Node* arguments_length = __ Load(
    3130             :         MachineType::TaggedSigned(), arguments_frame,
    3131         229 :         __ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset));
    3132             : 
    3133             :     Node* rest_length =
    3134         229 :         __ IntSub(arguments_length, __ SmiConstant(formal_parameter_count));
    3135         229 :     __ GotoIf(__ IntLessThan(rest_length, __ SmiConstant(0)), &done,
    3136         229 :               __ SmiConstant(0));
    3137             :     __ Goto(&done, rest_length);
    3138             : 
    3139             :     __ Bind(&done);
    3140             :     return done.PhiAt(0);
    3141             :   } else {
    3142             :     // The ArgumentsLength node is computing the actual number of arguments.
    3143             :     // We have to distinguish the case when there is an arguments adaptor frame
    3144             :     // (i.e., arguments_frame != LoadFramePointer()).
    3145       16712 :     auto if_adaptor_frame = __ MakeLabel();
    3146       33424 :     auto done = __ MakeLabel(MachineRepresentation::kTaggedSigned);
    3147             : 
    3148       16712 :     Node* frame = __ LoadFramePointer();
    3149       16712 :     __ GotoIf(__ WordEqual(arguments_frame, frame), &done,
    3150       16712 :               __ SmiConstant(formal_parameter_count));
    3151             :     __ Goto(&if_adaptor_frame);
    3152             : 
    3153             :     __ Bind(&if_adaptor_frame);
    3154       16712 :     Node* arguments_length = __ Load(
    3155             :         MachineType::TaggedSigned(), arguments_frame,
    3156       16712 :         __ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset));
    3157             :     __ Goto(&done, arguments_length);
    3158             : 
    3159             :     __ Bind(&done);
    3160             :     return done.PhiAt(0);
    3161             :   }
    3162             : }
    3163             : 
    3164       16914 : Node* EffectControlLinearizer::LowerArgumentsFrame(Node* node) {
    3165       33828 :   auto done = __ MakeLabel(MachineType::PointerRepresentation());
    3166             : 
    3167       16914 :   Node* frame = __ LoadFramePointer();
    3168             :   Node* parent_frame =
    3169       16914 :       __ Load(MachineType::Pointer(), frame,
    3170       16914 :               __ IntPtrConstant(StandardFrameConstants::kCallerFPOffset));
    3171       16914 :   Node* parent_frame_type = __ Load(
    3172             :       MachineType::AnyTagged(), parent_frame,
    3173       16914 :       __ IntPtrConstant(CommonFrameConstants::kContextOrFrameTypeOffset));
    3174       16914 :   __ GotoIf(__ WordEqual(parent_frame_type,
    3175             :                          __ IntPtrConstant(StackFrame::TypeToMarker(
    3176             :                              StackFrame::ARGUMENTS_ADAPTOR))),
    3177       16914 :             &done, parent_frame);
    3178             :   __ Goto(&done, frame);
    3179             : 
    3180             :   __ Bind(&done);
    3181       16914 :   return done.PhiAt(0);
    3182             : }
    3183             : 
    3184          28 : Node* EffectControlLinearizer::LowerNewDoubleElements(Node* node) {
    3185          28 :   AllocationType const allocation = AllocationTypeOf(node->op());
    3186             :   Node* length = node->InputAt(0);
    3187             : 
    3188          56 :   auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
    3189          28 :   Node* zero_length = __ WordEqual(length, __ IntPtrConstant(0));
    3190          56 :   __ GotoIf(zero_length, &done,
    3191          28 :             jsgraph()->HeapConstant(factory()->empty_fixed_array()));
    3192             : 
    3193             :   // Compute the effective size of the backing store.
    3194          28 :   Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kDoubleSizeLog2)),
    3195          28 :                          __ IntPtrConstant(FixedDoubleArray::kHeaderSize));
    3196             : 
    3197             :   // Allocate the result and initialize the header.
    3198          28 :   Node* result = __ Allocate(allocation, size);
    3199          56 :   __ StoreField(AccessBuilder::ForMap(), result,
    3200          28 :                 __ FixedDoubleArrayMapConstant());
    3201          56 :   __ StoreField(AccessBuilder::ForFixedArrayLength(), result,
    3202          28 :                 ChangeIntPtrToSmi(length));
    3203             : 
    3204             :   // Initialize the backing store with holes.
    3205             :   STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
    3206             :                                     Oddball::kToNumberRawOffset);
    3207             :   Node* the_hole =
    3208          28 :       __ LoadField(AccessBuilder::ForHeapNumberValue(), __ TheHoleConstant());
    3209          56 :   auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
    3210          28 :   __ Goto(&loop, __ IntPtrConstant(0));
    3211             :   __ Bind(&loop);
    3212             :   {
    3213             :     // Check if we've initialized everything.
    3214             :     Node* index = loop.PhiAt(0);
    3215          28 :     Node* check = __ UintLessThan(index, length);
    3216          28 :     __ GotoIfNot(check, &done, result);
    3217             : 
    3218             :     ElementAccess const access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
    3219             :                                   Type::NumberOrHole(), MachineType::Float64(),
    3220             :                                   kNoWriteBarrier};
    3221          28 :     __ StoreElement(access, result, index, the_hole);
    3222             : 
    3223             :     // Advance the {index}.
    3224          28 :     index = __ IntAdd(index, __ IntPtrConstant(1));
    3225             :     __ Goto(&loop, index);
    3226             :   }
    3227             : 
    3228             :   __ Bind(&done);
    3229          28 :   return done.PhiAt(0);
    3230             : }
    3231             : 
    3232         476 : Node* EffectControlLinearizer::LowerNewSmiOrObjectElements(Node* node) {
    3233         476 :   AllocationType const allocation = AllocationTypeOf(node->op());
    3234             :   Node* length = node->InputAt(0);
    3235             : 
    3236         952 :   auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
    3237         476 :   Node* zero_length = __ WordEqual(length, __ IntPtrConstant(0));
    3238         952 :   __ GotoIf(zero_length, &done,
    3239         476 :             jsgraph()->HeapConstant(factory()->empty_fixed_array()));
    3240             : 
    3241             :   // Compute the effective size of the backing store.
    3242         476 :   Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kTaggedSizeLog2)),
    3243         476 :                          __ IntPtrConstant(FixedArray::kHeaderSize));
    3244             : 
    3245             :   // Allocate the result and initialize the header.
    3246         476 :   Node* result = __ Allocate(allocation, size);
    3247         476 :   __ StoreField(AccessBuilder::ForMap(), result, __ FixedArrayMapConstant());
    3248         952 :   __ StoreField(AccessBuilder::ForFixedArrayLength(), result,
    3249         476 :                 ChangeIntPtrToSmi(length));
    3250             : 
    3251             :   // Initialize the backing store with holes.
    3252         476 :   Node* the_hole = __ TheHoleConstant();
    3253         952 :   auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
    3254         476 :   __ Goto(&loop, __ IntPtrConstant(0));
    3255             :   __ Bind(&loop);
    3256             :   {
    3257             :     // Check if we've initialized everything.
    3258             :     Node* index = loop.PhiAt(0);
    3259         476 :     Node* check = __ UintLessThan(index, length);
    3260         476 :     __ GotoIfNot(check, &done, result);
    3261             : 
    3262             :     // Storing "the_hole" doesn't need a write barrier.
    3263             :     ElementAccess const access = {kTaggedBase, FixedArray::kHeaderSize,
    3264             :                                   Type::Any(), MachineType::AnyTagged(),
    3265             :                                   kNoWriteBarrier};
    3266         476 :     __ StoreElement(access, result, index, the_hole);
    3267             : 
    3268             :     // Advance the {index}.
    3269         476 :     index = __ IntAdd(index, __ IntPtrConstant(1));
    3270             :     __ Goto(&loop, index);
    3271             :   }
    3272             : 
    3273             :   __ Bind(&done);
    3274         476 :   return done.PhiAt(0);
    3275             : }
    3276             : 
    3277       16437 : Node* EffectControlLinearizer::LowerNewArgumentsElements(Node* node) {
    3278       16437 :   Node* frame = NodeProperties::GetValueInput(node, 0);
    3279       16437 :   Node* length = NodeProperties::GetValueInput(node, 1);
    3280       16437 :   int mapped_count = NewArgumentsElementsMappedCountOf(node->op());
    3281             : 
    3282             :   Callable const callable =
    3283       16437 :       Builtins::CallableFor(isolate(), Builtins::kNewArgumentsElements);
    3284       16437 :   Operator::Properties const properties = node->op()->properties();
    3285             :   CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
    3286             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3287       16437 :       graph()->zone(), callable.descriptor(),
    3288       16437 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3289       49311 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), frame,
    3290       32874 :                  length, __ SmiConstant(mapped_count), __ NoContextConstant());
    3291             : }
    3292             : 
    3293        5193 : Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
    3294             :   Node* length = node->InputAt(0);
    3295             :   Node* first = node->InputAt(1);
    3296             :   Node* second = node->InputAt(2);
    3297             : 
    3298             :   // Determine the instance types of {first} and {second}.
    3299       10386 :   Node* first_map = __ LoadField(AccessBuilder::ForMap(), first);
    3300             :   Node* first_instance_type =
    3301        5193 :       __ LoadField(AccessBuilder::ForMapInstanceType(), first_map);
    3302        5193 :   Node* second_map = __ LoadField(AccessBuilder::ForMap(), second);
    3303             :   Node* second_instance_type =
    3304        5193 :       __ LoadField(AccessBuilder::ForMapInstanceType(), second_map);
    3305             : 
    3306             :   // Determine the proper map for the resulting ConsString.
    3307             :   // If both {first} and {second} are one-byte strings, we
    3308             :   // create a new ConsOneByteString, otherwise we create a
    3309             :   // new ConsString instead.
    3310        5193 :   auto if_onebyte = __ MakeLabel();
    3311        5193 :   auto if_twobyte = __ MakeLabel();
    3312       10386 :   auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
    3313             :   STATIC_ASSERT(kOneByteStringTag != 0);
    3314             :   STATIC_ASSERT(kTwoByteStringTag == 0);
    3315        5193 :   Node* instance_type = __ Word32And(first_instance_type, second_instance_type);
    3316             :   Node* encoding =
    3317        5193 :       __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask));
    3318        5193 :   __ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)),
    3319        5193 :             &if_twobyte, &if_onebyte);
    3320             :   __ Bind(&if_onebyte);
    3321       10386 :   __ Goto(&done,
    3322             :           jsgraph()->HeapConstant(factory()->cons_one_byte_string_map()));
    3323             :   __ Bind(&if_twobyte);
    3324       10386 :   __ Goto(&done, jsgraph()->HeapConstant(factory()->cons_string_map()));
    3325             :   __ Bind(&done);
    3326             :   Node* result_map = done.PhiAt(0);
    3327             : 
    3328             :   // Allocate the resulting ConsString.
    3329             :   Node* result =
    3330        5193 :       __ Allocate(AllocationType::kYoung, __ IntPtrConstant(ConsString::kSize));
    3331        5193 :   __ StoreField(AccessBuilder::ForMap(), result, result_map);
    3332       10386 :   __ StoreField(AccessBuilder::ForNameHashField(), result,
    3333        5193 :                 __ Int32Constant(Name::kEmptyHashField));
    3334        5193 :   __ StoreField(AccessBuilder::ForStringLength(), result, length);
    3335        5193 :   __ StoreField(AccessBuilder::ForConsStringFirst(), result, first);
    3336        5193 :   __ StoreField(AccessBuilder::ForConsStringSecond(), result, second);
    3337        5193 :   return result;
    3338             : }
    3339             : 
    3340           1 : Node* EffectControlLinearizer::LowerSameValue(Node* node) {
    3341             :   Node* lhs = node->InputAt(0);
    3342             :   Node* rhs = node->InputAt(1);
    3343             : 
    3344             :   Callable const callable =
    3345           1 :       Builtins::CallableFor(isolate(), Builtins::kSameValue);
    3346             :   Operator::Properties properties = Operator::kEliminatable;
    3347             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3348             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3349           1 :       graph()->zone(), callable.descriptor(),
    3350           1 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3351           3 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
    3352           2 :                  __ NoContextConstant());
    3353             : }
    3354             : 
    3355         162 : Node* EffectControlLinearizer::LowerSameValueNumbersOnly(Node* node) {
    3356             :   Node* lhs = node->InputAt(0);
    3357             :   Node* rhs = node->InputAt(1);
    3358             : 
    3359             :   Callable const callable =
    3360         162 :       Builtins::CallableFor(isolate(), Builtins::kSameValueNumbersOnly);
    3361             :   Operator::Properties properties = Operator::kEliminatable;
    3362             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3363             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3364         162 :       graph()->zone(), callable.descriptor(),
    3365         162 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3366         486 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
    3367         324 :                  __ NoContextConstant());
    3368             : }
    3369             : 
    3370          77 : Node* EffectControlLinearizer::LowerNumberSameValue(Node* node) {
    3371             :   Node* lhs = node->InputAt(0);
    3372             :   Node* rhs = node->InputAt(1);
    3373             : 
    3374          77 :   auto is_float64_equal = __ MakeLabel();
    3375         154 :   auto done = __ MakeLabel(MachineRepresentation::kBit);
    3376             : 
    3377          77 :   __ GotoIf(__ Float64Equal(lhs, rhs), &is_float64_equal);
    3378             : 
    3379             :   // Return true iff both {lhs} and {rhs} are NaN.
    3380          77 :   __ GotoIf(__ Float64Equal(lhs, lhs), &done, __ Int32Constant(0));
    3381          77 :   __ GotoIf(__ Float64Equal(rhs, rhs), &done, __ Int32Constant(0));
    3382          77 :   __ Goto(&done, __ Int32Constant(1));
    3383             : 
    3384             :   __ Bind(&is_float64_equal);
    3385             :   // Even if the values are float64-equal, we still need to distinguish
    3386             :   // zero and minus zero.
    3387          77 :   Node* lhs_hi = __ Float64ExtractHighWord32(lhs);
    3388          77 :   Node* rhs_hi = __ Float64ExtractHighWord32(rhs);
    3389          77 :   __ Goto(&done, __ Word32Equal(lhs_hi, rhs_hi));
    3390             : 
    3391             :   __ Bind(&done);
    3392          77 :   return done.PhiAt(0);
    3393             : }
    3394             : 
    3395        1303 : Node* EffectControlLinearizer::LowerDeadValue(Node* node) {
    3396        1303 :   Node* input = NodeProperties::GetValueInput(node, 0);
    3397        1303 :   if (input->opcode() != IrOpcode::kUnreachable) {
    3398        1001 :     Node* unreachable = __ Unreachable();
    3399        1001 :     NodeProperties::ReplaceValueInput(node, unreachable, 0);
    3400             :   }
    3401        1303 :   return node;
    3402             : }
    3403             : 
    3404         330 : Node* EffectControlLinearizer::LowerStringToNumber(Node* node) {
    3405             :   Node* string = node->InputAt(0);
    3406             : 
    3407             :   Callable const callable =
    3408         330 :       Builtins::CallableFor(isolate(), Builtins::kStringToNumber);
    3409             :   Operator::Properties properties = Operator::kEliminatable;
    3410             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3411             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3412         330 :       graph()->zone(), callable.descriptor(),
    3413         330 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3414         990 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), string,
    3415         660 :                  __ NoContextConstant());
    3416             : }
    3417             : 
    3418        2236 : Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
    3419             :   Node* receiver = node->InputAt(0);
    3420             :   Node* position = node->InputAt(1);
    3421             : 
    3422             :   // We need a loop here to properly deal with indirect strings
    3423             :   // (SlicedString, ConsString and ThinString).
    3424             :   auto loop = __ MakeLoopLabel(MachineRepresentation::kTagged,
    3425        4472 :                                MachineType::PointerRepresentation());
    3426             :   auto loop_next = __ MakeLabel(MachineRepresentation::kTagged,
    3427        4472 :                                 MachineType::PointerRepresentation());
    3428        4472 :   auto loop_done = __ MakeLabel(MachineRepresentation::kWord32);
    3429             :   __ Goto(&loop, receiver, position);
    3430             :   __ Bind(&loop);
    3431             :   {
    3432             :     Node* receiver = loop.PhiAt(0);
    3433             :     Node* position = loop.PhiAt(1);
    3434        2236 :     Node* receiver_map = __ LoadField(AccessBuilder::ForMap(), receiver);
    3435             :     Node* receiver_instance_type =
    3436        2236 :         __ LoadField(AccessBuilder::ForMapInstanceType(), receiver_map);
    3437        2236 :     Node* receiver_representation = __ Word32And(
    3438        2236 :         receiver_instance_type, __ Int32Constant(kStringRepresentationMask));
    3439             : 
    3440             :     // Dispatch on the current {receiver}s string representation.
    3441        2236 :     auto if_seqstring = __ MakeLabel();
    3442        2236 :     auto if_consstring = __ MakeLabel();
    3443        2236 :     auto if_thinstring = __ MakeLabel();
    3444        2236 :     auto if_externalstring = __ MakeLabel();
    3445        2236 :     auto if_slicedstring = __ MakeLabel();
    3446        2236 :     auto if_runtime = __ MakeDeferredLabel();
    3447        2236 :     __ GotoIf(__ Word32Equal(receiver_representation,
    3448             :                              __ Int32Constant(kSeqStringTag)),
    3449        2236 :               &if_seqstring);
    3450        2236 :     __ GotoIf(__ Word32Equal(receiver_representation,
    3451             :                              __ Int32Constant(kConsStringTag)),
    3452        2236 :               &if_consstring);
    3453        2236 :     __ GotoIf(__ Word32Equal(receiver_representation,
    3454             :                              __ Int32Constant(kThinStringTag)),
    3455        2236 :               &if_thinstring);
    3456        2236 :     __ GotoIf(__ Word32Equal(receiver_representation,
    3457             :                              __ Int32Constant(kExternalStringTag)),
    3458        2236 :               &if_externalstring);
    3459        2236 :     __ Branch(__ Word32Equal(receiver_representation,
    3460             :                              __ Int32Constant(kSlicedStringTag)),
    3461        2236 :               &if_slicedstring, &if_runtime);
    3462             : 
    3463             :     __ Bind(&if_seqstring);
    3464             :     {
    3465        2236 :       Node* receiver_is_onebyte = __ Word32Equal(
    3466             :           __ Word32Equal(__ Word32And(receiver_instance_type,
    3467             :                                       __ Int32Constant(kStringEncodingMask)),
    3468             :                          __ Int32Constant(kTwoByteStringTag)),
    3469        2236 :           __ Int32Constant(0));
    3470        2236 :       Node* result = LoadFromSeqString(receiver, position, receiver_is_onebyte);
    3471             :       __ Goto(&loop_done, result);
    3472             :     }
    3473             : 
    3474             :     __ Bind(&if_thinstring);
    3475             :     {
    3476             :       Node* receiver_actual =
    3477        2236 :           __ LoadField(AccessBuilder::ForThinStringActual(), receiver);
    3478             :       __ Goto(&loop_next, receiver_actual, position);
    3479             :     }
    3480             : 
    3481             :     __ Bind(&if_consstring);
    3482             :     {
    3483             :       Node* receiver_second =
    3484        2236 :           __ LoadField(AccessBuilder::ForConsStringSecond(), receiver);
    3485        2236 :       __ GotoIfNot(__ WordEqual(receiver_second, __ EmptyStringConstant()),
    3486        2236 :                    &if_runtime);
    3487             :       Node* receiver_first =
    3488        2236 :           __ LoadField(AccessBuilder::ForConsStringFirst(), receiver);
    3489             :       __ Goto(&loop_next, receiver_first, position);
    3490             :     }
    3491             : 
    3492             :     __ Bind(&if_externalstring);
    3493             :     {
    3494             :       // We need to bailout to the runtime for uncached external strings.
    3495        2236 :       __ GotoIf(__ Word32Equal(
    3496             :                     __ Word32And(receiver_instance_type,
    3497             :                                  __ Int32Constant(kUncachedExternalStringMask)),
    3498             :                     __ Int32Constant(kUncachedExternalStringTag)),
    3499        2236 :                 &if_runtime);
    3500             : 
    3501             :       Node* receiver_data = __ LoadField(
    3502        2236 :           AccessBuilder::ForExternalStringResourceData(), receiver);
    3503             : 
    3504        2236 :       auto if_onebyte = __ MakeLabel();
    3505        2236 :       auto if_twobyte = __ MakeLabel();
    3506        2236 :       __ Branch(
    3507             :           __ Word32Equal(__ Word32And(receiver_instance_type,
    3508             :                                       __ Int32Constant(kStringEncodingMask)),
    3509             :                          __ Int32Constant(kTwoByteStringTag)),
    3510        2236 :           &if_twobyte, &if_onebyte);
    3511             : 
    3512             :       __ Bind(&if_onebyte);
    3513             :       {
    3514        2236 :         Node* result = __ Load(MachineType::Uint8(), receiver_data, position);
    3515             :         __ Goto(&loop_done, result);
    3516             :       }
    3517             : 
    3518             :       __ Bind(&if_twobyte);
    3519             :       {
    3520        2236 :         Node* result = __ Load(MachineType::Uint16(), receiver_data,
    3521        2236 :                                __ WordShl(position, __ IntPtrConstant(1)));
    3522             :         __ Goto(&loop_done, result);
    3523             :       }
    3524             :     }
    3525             : 
    3526             :     __ Bind(&if_slicedstring);
    3527             :     {
    3528             :       Node* receiver_offset =
    3529        2236 :           __ LoadField(AccessBuilder::ForSlicedStringOffset(), receiver);
    3530             :       Node* receiver_parent =
    3531        2236 :           __ LoadField(AccessBuilder::ForSlicedStringParent(), receiver);
    3532        2236 :       __ Goto(&loop_next, receiver_parent,
    3533             :               __ IntAdd(position, ChangeSmiToIntPtr(receiver_offset)));
    3534             :     }
    3535             : 
    3536             :     __ Bind(&if_runtime);
    3537             :     {
    3538        2236 :       Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    3539             :       Runtime::FunctionId id = Runtime::kStringCharCodeAt;
    3540        2236 :       auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    3541        2236 :           graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
    3542        2236 :       Node* result = __ Call(call_descriptor, __ CEntryStubConstant(1),
    3543             :                              receiver, ChangeIntPtrToSmi(position),
    3544             :                              __ ExternalConstant(ExternalReference::Create(id)),
    3545        2236 :                              __ Int32Constant(2), __ NoContextConstant());
    3546        2236 :       __ Goto(&loop_done, ChangeSmiToInt32(result));
    3547             :     }
    3548             : 
    3549             :     __ Bind(&loop_next);
    3550             :     __ Goto(&loop, loop_next.PhiAt(0), loop_next.PhiAt(1));
    3551             :   }
    3552             :   __ Bind(&loop_done);
    3553        2236 :   return loop_done.PhiAt(0);
    3554             : }
    3555             : 
    3556         223 : Node* EffectControlLinearizer::LowerStringCodePointAt(
    3557             :     Node* node, UnicodeEncoding encoding) {
    3558             :   Node* receiver = node->InputAt(0);
    3559             :   Node* position = node->InputAt(1);
    3560             : 
    3561             :   Builtins::Name builtin = encoding == UnicodeEncoding::UTF16
    3562             :                                ? Builtins::kStringCodePointAtUTF16
    3563         223 :                                : Builtins::kStringCodePointAtUTF32;
    3564             : 
    3565         223 :   Callable const callable = Builtins::CallableFor(isolate(), builtin);
    3566         223 :   Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
    3567             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3568             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3569         223 :       graph()->zone(), callable.descriptor(),
    3570         223 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3571         669 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
    3572         446 :                  position, __ NoContextConstant());
    3573             : }
    3574             : 
    3575        2236 : Node* EffectControlLinearizer::LoadFromSeqString(Node* receiver, Node* position,
    3576             :                                                  Node* is_one_byte) {
    3577        2236 :   auto one_byte_load = __ MakeLabel();
    3578        4472 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    3579        2236 :   __ GotoIf(is_one_byte, &one_byte_load);
    3580             :   Node* two_byte_result = __ LoadElement(
    3581        2236 :       AccessBuilder::ForSeqTwoByteStringCharacter(), receiver, position);
    3582             :   __ Goto(&done, two_byte_result);
    3583             : 
    3584             :   __ Bind(&one_byte_load);
    3585             :   Node* one_byte_element = __ LoadElement(
    3586        2236 :       AccessBuilder::ForSeqOneByteStringCharacter(), receiver, position);
    3587             :   __ Goto(&done, one_byte_element);
    3588             : 
    3589             :   __ Bind(&done);
    3590        2236 :   return done.PhiAt(0);
    3591             : }
    3592             : 
    3593         946 : Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
    3594             :   Node* value = node->InputAt(0);
    3595         946 :   Node* code = __ Word32And(value, __ Uint32Constant(0xFFFF));
    3596             : 
    3597         946 :   auto if_not_one_byte = __ MakeDeferredLabel();
    3598         946 :   auto cache_miss = __ MakeDeferredLabel();
    3599        1892 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    3600             : 
    3601             :   // Check if the {code} is a one byte character
    3602         946 :   Node* check1 = __ Uint32LessThanOrEqual(
    3603         946 :       code, __ Uint32Constant(String::kMaxOneByteCharCode));
    3604         946 :   __ GotoIfNot(check1, &if_not_one_byte);
    3605             :   {
    3606             :     // Load the isolate wide single character string cache.
    3607         946 :     Node* cache = __ HeapConstant(factory()->single_character_string_cache());
    3608             : 
    3609             :     // Compute the {cache} index for {code}.
    3610         946 :     Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
    3611             : 
    3612             :     // Check if we have an entry for the {code} in the single character string
    3613             :     // cache already.
    3614             :     Node* entry =
    3615         946 :         __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
    3616             : 
    3617         946 :     Node* check2 = __ WordEqual(entry, __ UndefinedConstant());
    3618         946 :     __ GotoIf(check2, &cache_miss);
    3619             : 
    3620             :     // Use the {entry} from the {cache}.
    3621             :     __ Goto(&done, entry);
    3622             : 
    3623             :     __ Bind(&cache_miss);
    3624             :     {
    3625             :       // Allocate a new SeqOneByteString for {code}.
    3626             :       Node* vtrue2 =
    3627         946 :           __ Allocate(AllocationType::kYoung,
    3628         946 :                       __ IntPtrConstant(SeqOneByteString::SizeFor(1)));
    3629        1892 :       __ StoreField(AccessBuilder::ForMap(), vtrue2,
    3630         946 :                     __ HeapConstant(factory()->one_byte_string_map()));
    3631        1892 :       __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
    3632         946 :                     __ Int32Constant(Name::kEmptyHashField));
    3633        1892 :       __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
    3634         946 :                     __ Int32Constant(1));
    3635        1892 :       __ Store(
    3636             :           StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
    3637             :           vtrue2,
    3638             :           __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
    3639         946 :           code);
    3640             : 
    3641             :       // Remember it in the {cache}.
    3642        1892 :       __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
    3643         946 :                       vtrue2);
    3644             :       __ Goto(&done, vtrue2);
    3645             :     }
    3646             :   }
    3647             : 
    3648             :   __ Bind(&if_not_one_byte);
    3649             :   {
    3650             :     // Allocate a new SeqTwoByteString for {code}.
    3651             :     Node* vfalse1 =
    3652         946 :         __ Allocate(AllocationType::kYoung,
    3653         946 :                     __ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
    3654        1892 :     __ StoreField(AccessBuilder::ForMap(), vfalse1,
    3655         946 :                   __ HeapConstant(factory()->string_map()));
    3656        1892 :     __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
    3657         946 :                   __ Int32Constant(Name::kEmptyHashField));
    3658        1892 :     __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
    3659         946 :                   __ Int32Constant(1));
    3660        1892 :     __ Store(
    3661             :         StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
    3662             :         vfalse1,
    3663             :         __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
    3664         946 :         code);
    3665             :     __ Goto(&done, vfalse1);
    3666             :   }
    3667             : 
    3668             :   __ Bind(&done);
    3669         946 :   return done.PhiAt(0);
    3670             : }
    3671             : 
    3672             : #ifdef V8_INTL_SUPPORT
    3673             : 
    3674          96 : Node* EffectControlLinearizer::LowerStringToLowerCaseIntl(Node* node) {
    3675             :   Node* receiver = node->InputAt(0);
    3676             : 
    3677             :   Callable callable =
    3678          96 :       Builtins::CallableFor(isolate(), Builtins::kStringToLowerCaseIntl);
    3679          96 :   Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    3680             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3681             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3682          96 :       graph()->zone(), callable.descriptor(),
    3683          96 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3684         288 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
    3685         192 :                  __ NoContextConstant());
    3686             : }
    3687             : 
    3688          36 : Node* EffectControlLinearizer::LowerStringToUpperCaseIntl(Node* node) {
    3689             :   Node* receiver = node->InputAt(0);
    3690          36 :   Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    3691             :   Runtime::FunctionId id = Runtime::kStringToUpperCaseIntl;
    3692          36 :   auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    3693          36 :       graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
    3694          36 :   return __ Call(call_descriptor, __ CEntryStubConstant(1), receiver,
    3695             :                  __ ExternalConstant(ExternalReference::Create(id)),
    3696          36 :                  __ Int32Constant(1), __ NoContextConstant());
    3697             : }
    3698             : 
    3699             : #else
    3700             : 
    3701             : Node* EffectControlLinearizer::LowerStringToLowerCaseIntl(Node* node) {
    3702             :   UNREACHABLE();
    3703             :   return nullptr;
    3704             : }
    3705             : 
    3706             : Node* EffectControlLinearizer::LowerStringToUpperCaseIntl(Node* node) {
    3707             :   UNREACHABLE();
    3708             :   return nullptr;
    3709             : }
    3710             : 
    3711             : #endif  // V8_INTL_SUPPORT
    3712             : 
    3713         207 : Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
    3714             :   Node* value = node->InputAt(0);
    3715             :   Node* code = value;
    3716             : 
    3717         207 :   auto if_not_single_code = __ MakeDeferredLabel();
    3718         207 :   auto if_not_one_byte = __ MakeDeferredLabel();
    3719         207 :   auto cache_miss = __ MakeDeferredLabel();
    3720         414 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    3721             : 
    3722             :   // Check if the {code} is a single code unit
    3723         207 :   Node* check0 = __ Uint32LessThanOrEqual(code, __ Uint32Constant(0xFFFF));
    3724         207 :   __ GotoIfNot(check0, &if_not_single_code);
    3725             : 
    3726             :   {
    3727             :     // Check if the {code} is a one byte character
    3728         207 :     Node* check1 = __ Uint32LessThanOrEqual(
    3729         207 :         code, __ Uint32Constant(String::kMaxOneByteCharCode));
    3730         207 :     __ GotoIfNot(check1, &if_not_one_byte);
    3731             :     {
    3732             :       // Load the isolate wide single character string cache.
    3733         207 :       Node* cache = __ HeapConstant(factory()->single_character_string_cache());
    3734             : 
    3735             :       // Compute the {cache} index for {code}.
    3736         207 :       Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code);
    3737             : 
    3738             :       // Check if we have an entry for the {code} in the single character string
    3739             :       // cache already.
    3740             :       Node* entry =
    3741         207 :           __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index);
    3742             : 
    3743         207 :       Node* check2 = __ WordEqual(entry, __ UndefinedConstant());
    3744         207 :       __ GotoIf(check2, &cache_miss);
    3745             : 
    3746             :       // Use the {entry} from the {cache}.
    3747             :       __ Goto(&done, entry);
    3748             : 
    3749             :       __ Bind(&cache_miss);
    3750             :       {
    3751             :         // Allocate a new SeqOneByteString for {code}.
    3752             :         Node* vtrue2 =
    3753         207 :             __ Allocate(AllocationType::kYoung,
    3754         207 :                         __ IntPtrConstant(SeqOneByteString::SizeFor(1)));
    3755         414 :         __ StoreField(AccessBuilder::ForMap(), vtrue2,
    3756         207 :                       __ HeapConstant(factory()->one_byte_string_map()));
    3757         414 :         __ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
    3758         207 :                       __ Int32Constant(Name::kEmptyHashField));
    3759         414 :         __ StoreField(AccessBuilder::ForStringLength(), vtrue2,
    3760         207 :                       __ Int32Constant(1));
    3761         414 :         __ Store(
    3762             :             StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
    3763             :             vtrue2,
    3764             :             __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
    3765         207 :             code);
    3766             : 
    3767             :         // Remember it in the {cache}.
    3768         414 :         __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index,
    3769         207 :                         vtrue2);
    3770             :         __ Goto(&done, vtrue2);
    3771             :       }
    3772             :     }
    3773             : 
    3774             :     __ Bind(&if_not_one_byte);
    3775             :     {
    3776             :       // Allocate a new SeqTwoByteString for {code}.
    3777             :       Node* vfalse1 =
    3778         207 :           __ Allocate(AllocationType::kYoung,
    3779         207 :                       __ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
    3780         414 :       __ StoreField(AccessBuilder::ForMap(), vfalse1,
    3781         207 :                     __ HeapConstant(factory()->string_map()));
    3782         414 :       __ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
    3783         207 :                     __ IntPtrConstant(Name::kEmptyHashField));
    3784         414 :       __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
    3785         207 :                     __ Int32Constant(1));
    3786         414 :       __ Store(
    3787             :           StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
    3788             :           vfalse1,
    3789             :           __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
    3790         207 :           code);
    3791             :       __ Goto(&done, vfalse1);
    3792             :     }
    3793             :   }
    3794             : 
    3795             :   __ Bind(&if_not_single_code);
    3796             :   // Generate surrogate pair string
    3797             :   {
    3798         207 :     switch (UnicodeEncodingOf(node->op())) {
    3799             :       case UnicodeEncoding::UTF16:
    3800             :         break;
    3801             : 
    3802             :       case UnicodeEncoding::UTF32: {
    3803             :         // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
    3804          92 :         Node* lead_offset = __ Int32Constant(0xD800 - (0x10000 >> 10));
    3805             : 
    3806             :         // lead = (codepoint >> 10) + LEAD_OFFSET
    3807             :         Node* lead =
    3808          92 :             __ Int32Add(__ Word32Shr(code, __ Int32Constant(10)), lead_offset);
    3809             : 
    3810             :         // trail = (codepoint & 0x3FF) + 0xDC00;
    3811          92 :         Node* trail = __ Int32Add(__ Word32And(code, __ Int32Constant(0x3FF)),
    3812          92 :                                   __ Int32Constant(0xDC00));
    3813             : 
    3814             :         // codpoint = (trail << 16) | lead;
    3815             : #if V8_TARGET_BIG_ENDIAN
    3816             :         code = __ Word32Or(__ Word32Shl(lead, __ Int32Constant(16)), trail);
    3817             : #else
    3818          92 :         code = __ Word32Or(__ Word32Shl(trail, __ Int32Constant(16)), lead);
    3819             : #endif
    3820          92 :         break;
    3821             :       }
    3822             :     }
    3823             : 
    3824             :     // Allocate a new SeqTwoByteString for {code}.
    3825             :     Node* vfalse0 =
    3826         207 :         __ Allocate(AllocationType::kYoung,
    3827         207 :                     __ IntPtrConstant(SeqTwoByteString::SizeFor(2)));
    3828         414 :     __ StoreField(AccessBuilder::ForMap(), vfalse0,
    3829         207 :                   __ HeapConstant(factory()->string_map()));
    3830         414 :     __ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
    3831         207 :                   __ Int32Constant(Name::kEmptyHashField));
    3832         414 :     __ StoreField(AccessBuilder::ForStringLength(), vfalse0,
    3833         207 :                   __ Int32Constant(2));
    3834         414 :     __ Store(
    3835             :         StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
    3836             :         vfalse0,
    3837             :         __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
    3838         207 :         code);
    3839             :     __ Goto(&done, vfalse0);
    3840             :   }
    3841             : 
    3842             :   __ Bind(&done);
    3843         207 :   return done.PhiAt(0);
    3844             : }
    3845             : 
    3846         268 : Node* EffectControlLinearizer::LowerStringIndexOf(Node* node) {
    3847             :   Node* subject = node->InputAt(0);
    3848             :   Node* search_string = node->InputAt(1);
    3849             :   Node* position = node->InputAt(2);
    3850             : 
    3851             :   Callable callable =
    3852         268 :       Builtins::CallableFor(isolate(), Builtins::kStringIndexOf);
    3853             :   Operator::Properties properties = Operator::kEliminatable;
    3854             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3855             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3856         268 :       graph()->zone(), callable.descriptor(),
    3857         268 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3858         804 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), subject,
    3859         536 :                  search_string, position, __ NoContextConstant());
    3860             : }
    3861             : 
    3862       24595 : Node* EffectControlLinearizer::LowerStringLength(Node* node) {
    3863             :   Node* subject = node->InputAt(0);
    3864             : 
    3865       49190 :   return __ LoadField(AccessBuilder::ForStringLength(), subject);
    3866             : }
    3867             : 
    3868       11119 : Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable,
    3869             :                                                      Node* node) {
    3870             :   Node* lhs = node->InputAt(0);
    3871             :   Node* rhs = node->InputAt(1);
    3872             : 
    3873             :   Operator::Properties properties = Operator::kEliminatable;
    3874             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3875             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3876       11119 :       graph()->zone(), callable.descriptor(),
    3877       11119 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3878       33357 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
    3879       22238 :                  __ NoContextConstant());
    3880             : }
    3881             : 
    3882        1080 : Node* EffectControlLinearizer::LowerStringSubstring(Node* node) {
    3883             :   Node* receiver = node->InputAt(0);
    3884             :   Node* start = ChangeInt32ToIntPtr(node->InputAt(1));
    3885             :   Node* end = ChangeInt32ToIntPtr(node->InputAt(2));
    3886             : 
    3887             :   Callable callable =
    3888        1080 :       Builtins::CallableFor(isolate(), Builtins::kStringSubstring);
    3889             :   Operator::Properties properties = Operator::kEliminatable;
    3890             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3891             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    3892        1080 :       graph()->zone(), callable.descriptor(),
    3893        1080 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    3894        3240 :   return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
    3895        2160 :                  start, end, __ NoContextConstant());
    3896             : }
    3897             : 
    3898       10299 : Node* EffectControlLinearizer::LowerStringEqual(Node* node) {
    3899             :   return LowerStringComparison(
    3900       20598 :       Builtins::CallableFor(isolate(), Builtins::kStringEqual), node);
    3901             : }
    3902             : 
    3903         121 : Node* EffectControlLinearizer::LowerStringLessThan(Node* node) {
    3904             :   return LowerStringComparison(
    3905         242 :       Builtins::CallableFor(isolate(), Builtins::kStringLessThan), node);
    3906             : }
    3907             : 
    3908         699 : Node* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) {
    3909             :   return LowerStringComparison(
    3910        1398 :       Builtins::CallableFor(isolate(), Builtins::kStringLessThanOrEqual), node);
    3911             : }
    3912             : 
    3913         470 : Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node,
    3914             :                                                      Node* frame_state) {
    3915             :   // If we reach this point w/o eliminating the {node} that's marked
    3916             :   // with allow-return-hole, we cannot do anything, so just deoptimize
    3917             :   // in case of the hole NaN.
    3918             :   CheckFloat64HoleParameters const& params =
    3919         470 :       CheckFloat64HoleParametersOf(node->op());
    3920             :   Node* value = node->InputAt(0);
    3921             : 
    3922         470 :   auto if_nan = __ MakeDeferredLabel();
    3923         470 :   auto done = __ MakeLabel();
    3924             : 
    3925             :   // First check whether {value} is a NaN at all...
    3926         470 :   __ Branch(__ Float64Equal(value, value), &done, &if_nan);
    3927             : 
    3928             :   __ Bind(&if_nan);
    3929             :   {
    3930             :     // ...and only if {value} is a NaN, perform the expensive bit
    3931             :     // check. See http://crbug.com/v8/8264 for details.
    3932         470 :     Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
    3933         470 :                                  __ Int32Constant(kHoleNanUpper32));
    3934             :     __ DeoptimizeIf(DeoptimizeReason::kHole, params.feedback(), check,
    3935         470 :                     frame_state);
    3936             :     __ Goto(&done);
    3937             :   }
    3938             : 
    3939             :   __ Bind(&done);
    3940         470 :   return value;
    3941             : }
    3942             : 
    3943         102 : Node* EffectControlLinearizer::LowerCheckNotTaggedHole(Node* node,
    3944             :                                                        Node* frame_state) {
    3945             :   Node* value = node->InputAt(0);
    3946         102 :   Node* check = __ WordEqual(value, __ TheHoleConstant());
    3947         204 :   __ DeoptimizeIf(DeoptimizeReason::kHole, VectorSlotPair(), check,
    3948         102 :                   frame_state);
    3949         102 :   return value;
    3950             : }
    3951             : 
    3952        1668 : Node* EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node) {
    3953             :   Node* value = node->InputAt(0);
    3954             : 
    3955        1668 :   auto if_is_hole = __ MakeDeferredLabel();
    3956        3336 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    3957             : 
    3958        1668 :   Node* check = __ WordEqual(value, __ TheHoleConstant());
    3959        1668 :   __ GotoIf(check, &if_is_hole);
    3960             :   __ Goto(&done, value);
    3961             : 
    3962             :   __ Bind(&if_is_hole);
    3963        1668 :   __ Goto(&done, __ UndefinedConstant());
    3964             : 
    3965             :   __ Bind(&done);
    3966        1668 :   return done.PhiAt(0);
    3967             : }
    3968             : 
    3969         109 : void EffectControlLinearizer::LowerCheckEqualsInternalizedString(
    3970             :     Node* node, Node* frame_state) {
    3971             :   Node* exp = node->InputAt(0);
    3972             :   Node* val = node->InputAt(1);
    3973             : 
    3974         109 :   auto if_same = __ MakeLabel();
    3975         109 :   auto if_notsame = __ MakeDeferredLabel();
    3976         109 :   auto if_thinstring = __ MakeLabel();
    3977         109 :   auto if_notthinstring = __ MakeLabel();
    3978             : 
    3979             :   // Check if {exp} and {val} are the same, which is the likely case.
    3980         109 :   __ Branch(__ WordEqual(exp, val), &if_same, &if_notsame);
    3981             : 
    3982             :   __ Bind(&if_notsame);
    3983             :   {
    3984             :     // Now {val} could still be a non-internalized String that matches {exp}.
    3985         218 :     __ DeoptimizeIf(DeoptimizeReason::kWrongName, VectorSlotPair(),
    3986         109 :                     ObjectIsSmi(val), frame_state);
    3987         109 :     Node* val_map = __ LoadField(AccessBuilder::ForMap(), val);
    3988             :     Node* val_instance_type =
    3989         109 :         __ LoadField(AccessBuilder::ForMapInstanceType(), val_map);
    3990             : 
    3991             :     // Check for the common case of ThinString first.
    3992         109 :     __ GotoIf(__ Word32Equal(val_instance_type,
    3993             :                              __ Int32Constant(THIN_ONE_BYTE_STRING_TYPE)),
    3994         109 :               &if_thinstring);
    3995         109 :     __ Branch(
    3996             :         __ Word32Equal(val_instance_type, __ Int32Constant(THIN_STRING_TYPE)),
    3997         109 :         &if_thinstring, &if_notthinstring);
    3998             : 
    3999             :     __ Bind(&if_notthinstring);
    4000             :     {
    4001             :       // Check that the {val} is a non-internalized String, if it's anything
    4002             :       // else it cannot match the recorded feedback {exp} anyways.
    4003         218 :       __ DeoptimizeIfNot(
    4004             :           DeoptimizeReason::kWrongName, VectorSlotPair(),
    4005             :           __ Word32Equal(__ Word32And(val_instance_type,
    4006             :                                       __ Int32Constant(kIsNotStringMask |
    4007             :                                                        kIsNotInternalizedMask)),
    4008             :                          __ Int32Constant(kStringTag | kNotInternalizedTag)),
    4009         109 :           frame_state);
    4010             : 
    4011             :       // Try to find the {val} in the string table.
    4012             :       MachineSignature::Builder builder(graph()->zone(), 1, 2);
    4013             :       builder.AddReturn(MachineType::AnyTagged());
    4014             :       builder.AddParam(MachineType::Pointer());
    4015             :       builder.AddParam(MachineType::AnyTagged());
    4016         109 :       Node* try_internalize_string_function = __ ExternalConstant(
    4017         109 :           ExternalReference::try_internalize_string_function());
    4018             :       Node* const isolate_ptr =
    4019         109 :           __ ExternalConstant(ExternalReference::isolate_address(isolate()));
    4020             :       auto call_descriptor =
    4021         109 :           Linkage::GetSimplifiedCDescriptor(graph()->zone(), builder.Build());
    4022             :       Node* val_internalized =
    4023         109 :           __ Call(common()->Call(call_descriptor),
    4024         109 :                   try_internalize_string_function, isolate_ptr, val);
    4025             : 
    4026             :       // Now see if the results match.
    4027         218 :       __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(),
    4028         109 :                          __ WordEqual(exp, val_internalized), frame_state);
    4029             :       __ Goto(&if_same);
    4030             :     }
    4031             : 
    4032             :     __ Bind(&if_thinstring);
    4033             :     {
    4034             :       // The {val} is a ThinString, let's check the actual value.
    4035             :       Node* val_actual =
    4036         109 :           __ LoadField(AccessBuilder::ForThinStringActual(), val);
    4037         218 :       __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(),
    4038         109 :                          __ WordEqual(exp, val_actual), frame_state);
    4039             :       __ Goto(&if_same);
    4040             :     }
    4041             :   }
    4042             : 
    4043             :   __ Bind(&if_same);
    4044         109 : }
    4045             : 
    4046          18 : void EffectControlLinearizer::LowerCheckEqualsSymbol(Node* node,
    4047             :                                                      Node* frame_state) {
    4048             :   Node* exp = node->InputAt(0);
    4049             :   Node* val = node->InputAt(1);
    4050          18 :   Node* check = __ WordEqual(exp, val);
    4051          36 :   __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(), check,
    4052          18 :                      frame_state);
    4053          18 : }
    4054             : 
    4055       54788 : Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) {
    4056             :   Node* result =
    4057       54788 :       __ Allocate(AllocationType::kYoung, __ IntPtrConstant(HeapNumber::kSize));
    4058       54789 :   __ StoreField(AccessBuilder::ForMap(), result, __ HeapNumberMapConstant());
    4059       54788 :   __ StoreField(AccessBuilder::ForHeapNumberValue(), result, value);
    4060       54789 :   return result;
    4061             : }
    4062             : 
    4063      135067 : Node* EffectControlLinearizer::ChangeIntPtrToSmi(Node* value) {
    4064             :   // Do shift on 32bit values if Smis are stored in the lower word.
    4065             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4066             :     return __ ChangeInt32ToInt64(
    4067             :         __ Word32Shl(__ TruncateInt64ToInt32(value), SmiShiftBitsConstant()));
    4068             :   }
    4069      135067 :   return __ WordShl(value, SmiShiftBitsConstant());
    4070             : }
    4071             : 
    4072           0 : Node* EffectControlLinearizer::ChangeInt32ToIntPtr(Node* value) {
    4073      134238 :   if (machine()->Is64()) {
    4074      134238 :     value = __ ChangeInt32ToInt64(value);
    4075             :   }
    4076           0 :   return value;
    4077             : }
    4078             : 
    4079           0 : Node* EffectControlLinearizer::ChangeIntPtrToInt32(Node* value) {
    4080           0 :   if (machine()->Is64()) {
    4081           0 :     value = __ TruncateInt64ToInt32(value);
    4082             :   }
    4083           0 :   return value;
    4084             : }
    4085             : 
    4086      132078 : Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
    4087             :   // Do shift on 32bit values if Smis are stored in the lower word.
    4088             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4089             :     return __ ChangeInt32ToInt64(__ Word32Shl(value, SmiShiftBitsConstant()));
    4090             :   }
    4091      132078 :   return ChangeIntPtrToSmi(ChangeInt32ToIntPtr(value));
    4092             : }
    4093             : 
    4094           0 : Node* EffectControlLinearizer::ChangeInt64ToSmi(Node* value) {
    4095             :   DCHECK(machine()->Is64());
    4096         249 :   return ChangeIntPtrToSmi(value);
    4097             : }
    4098             : 
    4099           0 : Node* EffectControlLinearizer::ChangeUint32ToUintPtr(Node* value) {
    4100         662 :   if (machine()->Is64()) {
    4101         662 :     value = __ ChangeUint32ToUint64(value);
    4102             :   }
    4103           0 :   return value;
    4104             : }
    4105             : 
    4106         646 : Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
    4107             :   // Do shift on 32bit values if Smis are stored in the lower word.
    4108             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4109             :     return __ ChangeUint32ToUint64(__ Word32Shl(value, SmiShiftBitsConstant()));
    4110             :   } else {
    4111         646 :     return __ WordShl(ChangeUint32ToUintPtr(value), SmiShiftBitsConstant());
    4112             :   }
    4113             : }
    4114             : 
    4115      148833 : Node* EffectControlLinearizer::ChangeSmiToIntPtr(Node* value) {
    4116             :   // Do shift on 32bit values if Smis are stored in the lower word.
    4117             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4118             :     return __ ChangeInt32ToInt64(
    4119             :         __ Word32Sar(__ TruncateInt64ToInt32(value), SmiShiftBitsConstant()));
    4120             :   }
    4121      148833 :   return __ WordSar(value, SmiShiftBitsConstant());
    4122             : }
    4123             : 
    4124      146177 : Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
    4125             :   // Do shift on 32bit values if Smis are stored in the lower word.
    4126             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4127             :     return __ Word32Sar(__ TruncateInt64ToInt32(value), SmiShiftBitsConstant());
    4128             :   }
    4129      146177 :   if (machine()->Is64()) {
    4130      292356 :     return __ TruncateInt64ToInt32(ChangeSmiToIntPtr(value));
    4131             :   }
    4132           0 :   return ChangeSmiToIntPtr(value);
    4133             : }
    4134             : 
    4135         372 : Node* EffectControlLinearizer::ChangeSmiToInt64(Node* value) {
    4136         372 :   CHECK(machine()->Is64());
    4137         372 :   return ChangeSmiToIntPtr(value);
    4138             : }
    4139             : 
    4140      256736 : Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
    4141      256736 :   return __ WordEqual(__ WordAnd(value, __ IntPtrConstant(kSmiTagMask)),
    4142      256737 :                       __ IntPtrConstant(kSmiTag));
    4143             : }
    4144             : 
    4145           0 : Node* EffectControlLinearizer::SmiMaxValueConstant() {
    4146         646 :   return __ Int32Constant(Smi::kMaxValue);
    4147             : }
    4148             : 
    4149           0 : Node* EffectControlLinearizer::SmiShiftBitsConstant() {
    4150             :   if (machine()->Is64() && SmiValuesAre31Bits()) {
    4151             :     return __ Int32Constant(kSmiShiftSize + kSmiTagSize);
    4152             :   }
    4153      284546 :   return __ IntPtrConstant(kSmiShiftSize + kSmiTagSize);
    4154             : }
    4155             : 
    4156          20 : Node* EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node) {
    4157             :   Node* value = node->InputAt(0);
    4158          20 :   return __ ToNumber(value);
    4159             : }
    4160             : 
    4161           9 : Node* EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node) {
    4162             :   Node* value = node->InputAt(0);
    4163             : 
    4164           9 :   auto if_not_smi = __ MakeDeferredLabel();
    4165           9 :   auto if_to_number_smi = __ MakeLabel();
    4166          18 :   auto done = __ MakeLabel(MachineRepresentation::kWord32);
    4167             : 
    4168           9 :   Node* check0 = ObjectIsSmi(value);
    4169           9 :   __ GotoIfNot(check0, &if_not_smi);
    4170           9 :   __ Goto(&done, ChangeSmiToInt32(value));
    4171             : 
    4172             :   __ Bind(&if_not_smi);
    4173           9 :   Node* to_number = __ ToNumber(value);
    4174             : 
    4175           9 :   Node* check1 = ObjectIsSmi(to_number);
    4176           9 :   __ GotoIf(check1, &if_to_number_smi);
    4177           9 :   Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
    4178           9 :   __ Goto(&done, __ TruncateFloat64ToWord32(number));
    4179             : 
    4180             :   __ Bind(&if_to_number_smi);
    4181           9 :   __ Goto(&done, ChangeSmiToInt32(to_number));
    4182             : 
    4183             :   __ Bind(&done);
    4184           9 :   return done.PhiAt(0);
    4185             : }
    4186             : 
    4187           0 : Node* EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node) {
    4188             :   Node* value = node->InputAt(0);
    4189             : 
    4190           0 :   auto if_not_smi = __ MakeDeferredLabel();
    4191           0 :   auto if_to_number_smi = __ MakeLabel();
    4192           0 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    4193             : 
    4194           0 :   Node* check0 = ObjectIsSmi(value);
    4195           0 :   __ GotoIfNot(check0, &if_not_smi);
    4196           0 :   Node* from_smi = ChangeSmiToInt32(value);
    4197           0 :   __ Goto(&done, __ ChangeInt32ToFloat64(from_smi));
    4198             : 
    4199             :   __ Bind(&if_not_smi);
    4200           0 :   Node* to_number = __ ToNumber(value);
    4201           0 :   Node* check1 = ObjectIsSmi(to_number);
    4202           0 :   __ GotoIf(check1, &if_to_number_smi);
    4203             : 
    4204           0 :   Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number);
    4205             :   __ Goto(&done, number);
    4206             : 
    4207             :   __ Bind(&if_to_number_smi);
    4208           0 :   Node* number_from_smi = ChangeSmiToInt32(to_number);
    4209           0 :   number_from_smi = __ ChangeInt32ToFloat64(number_from_smi);
    4210             :   __ Goto(&done, number_from_smi);
    4211             : 
    4212             :   __ Bind(&done);
    4213           0 :   return done.PhiAt(0);
    4214             : }
    4215             : 
    4216        1683 : Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) {
    4217             :   Node* object = node->InputAt(0);
    4218             :   Node* elements = node->InputAt(1);
    4219             : 
    4220        1683 :   auto if_not_fixed_array = __ MakeDeferredLabel();
    4221        3366 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    4222             : 
    4223             :   // Load the current map of {elements}.
    4224        3366 :   Node* elements_map = __ LoadField(AccessBuilder::ForMap(), elements);
    4225             : 
    4226             :   // Check if {elements} is not a copy-on-write FixedArray.
    4227        1683 :   Node* check = __ WordEqual(elements_map, __ FixedArrayMapConstant());
    4228        1683 :   __ GotoIfNot(check, &if_not_fixed_array);
    4229             :   // Nothing to do if the {elements} are not copy-on-write.
    4230             :   __ Goto(&done, elements);
    4231             : 
    4232             :   __ Bind(&if_not_fixed_array);
    4233             :   // We need to take a copy of the {elements} and set them up for {object}.
    4234             :   Operator::Properties properties = Operator::kEliminatable;
    4235             :   Callable callable =
    4236        1683 :       Builtins::CallableFor(isolate(), Builtins::kCopyFastSmiOrObjectElements);
    4237             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    4238             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    4239        1683 :       graph()->zone(), callable.descriptor(),
    4240        1683 :       callable.descriptor().GetStackParameterCount(), flags, properties);
    4241        5049 :   Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
    4242        1683 :                          object, __ NoContextConstant());
    4243             :   __ Goto(&done, result);
    4244             : 
    4245             :   __ Bind(&done);
    4246        1683 :   return done.PhiAt(0);
    4247             : }
    4248             : 
    4249        3516 : Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
    4250             :                                                           Node* frame_state) {
    4251        3516 :   GrowFastElementsParameters params = GrowFastElementsParametersOf(node->op());
    4252             :   Node* object = node->InputAt(0);
    4253             :   Node* elements = node->InputAt(1);
    4254             :   Node* index = node->InputAt(2);
    4255             :   Node* elements_length = node->InputAt(3);
    4256             : 
    4257        7032 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    4258        3516 :   auto if_grow = __ MakeDeferredLabel();
    4259             :   auto if_not_grow = __ MakeLabel();
    4260             : 
    4261             :   // Check if we need to grow the {elements} backing store.
    4262        3516 :   Node* check = __ Uint32LessThan(index, elements_length);
    4263        3516 :   __ GotoIfNot(check, &if_grow);
    4264             :   __ Goto(&done, elements);
    4265             : 
    4266             :   __ Bind(&if_grow);
    4267             :   // We need to grow the {elements} for {object}.
    4268             :   Operator::Properties properties = Operator::kEliminatable;
    4269             :   Callable callable =
    4270             :       (params.mode() == GrowFastElementsMode::kDoubleElements)
    4271             :           ? Builtins::CallableFor(isolate(), Builtins::kGrowFastDoubleElements)
    4272             :           : Builtins::CallableFor(isolate(),
    4273        3516 :                                   Builtins::kGrowFastSmiOrObjectElements);
    4274             :   CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags;
    4275             :   auto call_descriptor = Linkage::GetStubCallDescriptor(
    4276        3516 :       graph()->zone(), callable.descriptor(),
    4277        3516 :       callable.descriptor().GetStackParameterCount(), call_flags, properties);
    4278             :   Node* new_elements =
    4279       10548 :       __ Call(call_descriptor, __ HeapConstant(callable.code()), object,
    4280        3516 :               ChangeInt32ToSmi(index), __ NoContextConstant());
    4281             : 
    4282             :   // Ensure that we were able to grow the {elements}.
    4283        3516 :   __ DeoptimizeIf(DeoptimizeReason::kCouldNotGrowElements, params.feedback(),
    4284        3516 :                   ObjectIsSmi(new_elements), frame_state);
    4285             :   __ Goto(&done, new_elements);
    4286             : 
    4287             :   __ Bind(&done);
    4288        3516 :   return done.PhiAt(0);
    4289             : }
    4290             : 
    4291         630 : void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) {
    4292         630 :   ElementsTransition const transition = ElementsTransitionOf(node->op());
    4293             :   Node* object = node->InputAt(0);
    4294             : 
    4295         630 :   auto if_map_same = __ MakeDeferredLabel();
    4296         630 :   auto done = __ MakeLabel();
    4297             : 
    4298         630 :   Node* source_map = __ HeapConstant(transition.source());
    4299         630 :   Node* target_map = __ HeapConstant(transition.target());
    4300             : 
    4301             :   // Load the current map of {object}.
    4302         630 :   Node* object_map = __ LoadField(AccessBuilder::ForMap(), object);
    4303             : 
    4304             :   // Check if {object_map} is the same as {source_map}.
    4305         630 :   Node* check = __ WordEqual(object_map, source_map);
    4306         630 :   __ GotoIf(check, &if_map_same);
    4307             :   __ Goto(&done);
    4308             : 
    4309             :   __ Bind(&if_map_same);
    4310         630 :   switch (transition.mode()) {
    4311             :     case ElementsTransition::kFastTransition:
    4312             :       // In-place migration of {object}, just store the {target_map}.
    4313         232 :       __ StoreField(AccessBuilder::ForMap(), object, target_map);
    4314         232 :       break;
    4315             :     case ElementsTransition::kSlowTransition: {
    4316             :       // Instance migration, call out to the runtime for {object}.
    4317         398 :       Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    4318             :       Runtime::FunctionId id = Runtime::kTransitionElementsKind;
    4319         398 :       auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    4320         398 :           graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
    4321         398 :       __ Call(call_descriptor, __ CEntryStubConstant(1), object, target_map,
    4322             :               __ ExternalConstant(ExternalReference::Create(id)),
    4323         398 :               __ Int32Constant(2), __ NoContextConstant());
    4324             :       break;
    4325             :     }
    4326             :   }
    4327             :   __ Goto(&done);
    4328             : 
    4329             :   __ Bind(&done);
    4330         630 : }
    4331             : 
    4332        7217 : Node* EffectControlLinearizer::LowerLoadMessage(Node* node) {
    4333             :   Node* offset = node->InputAt(0);
    4334             :   Node* object_pattern =
    4335       14434 :       __ LoadField(AccessBuilder::ForExternalIntPtr(), offset);
    4336        7217 :   return __ BitcastWordToTagged(object_pattern);
    4337             : }
    4338             : 
    4339       29703 : void EffectControlLinearizer::LowerStoreMessage(Node* node) {
    4340             :   Node* offset = node->InputAt(0);
    4341             :   Node* object = node->InputAt(1);
    4342       29703 :   Node* object_pattern = __ BitcastTaggedToWord(object);
    4343       29703 :   __ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern);
    4344       29703 : }
    4345             : 
    4346         582 : Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
    4347             :   Node* object = node->InputAt(0);
    4348             :   Node* index = node->InputAt(1);
    4349         582 :   Node* zero = __ IntPtrConstant(0);
    4350         582 :   Node* one = __ IntPtrConstant(1);
    4351             : 
    4352             :   // Sign-extend the {index} on 64-bit architectures.
    4353         582 :   if (machine()->Is64()) {
    4354         582 :     index = __ ChangeInt32ToInt64(index);
    4355             :   }
    4356             : 
    4357         582 :   auto if_double = __ MakeDeferredLabel();
    4358        1164 :   auto done = __ MakeLabel(MachineRepresentation::kTagged);
    4359             : 
    4360             :   // Check if field is a mutable double field.
    4361         582 :   __ GotoIfNot(__ WordEqual(__ WordAnd(index, one), zero), &if_double);
    4362             : 
    4363             :   // The field is a proper Tagged field on {object}. The {index} is shifted
    4364             :   // to the left by one in the code below.
    4365             :   {
    4366             :     // Check if field is in-object or out-of-object.
    4367         582 :     auto if_outofobject = __ MakeLabel();
    4368         582 :     __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
    4369             : 
    4370             :     // The field is located in the {object} itself.
    4371             :     {
    4372             :       Node* offset =
    4373         582 :           __ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2 - 1)),
    4374         582 :                     __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
    4375         582 :       Node* result = __ Load(MachineType::AnyTagged(), object, offset);
    4376             :       __ Goto(&done, result);
    4377             :     }
    4378             : 
    4379             :     // The field is located in the properties backing store of {object}.
    4380             :     // The {index} is equal to the negated out of property index plus 1.
    4381             :     __ Bind(&if_outofobject);
    4382             :     {
    4383             :       Node* properties =
    4384         582 :           __ LoadField(AccessBuilder::ForJSObjectPropertiesOrHash(), object);
    4385             :       Node* offset =
    4386         582 :           __ IntAdd(__ WordShl(__ IntSub(zero, index),
    4387             :                                __ IntPtrConstant(kTaggedSizeLog2 - 1)),
    4388             :                     __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
    4389         582 :                                       kHeapObjectTag));
    4390         582 :       Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
    4391             :       __ Goto(&done, result);
    4392             :     }
    4393             :   }
    4394             : 
    4395             :   // The field is a Double field, either unboxed in the object on 64-bit
    4396             :   // architectures, or as MutableHeapNumber.
    4397             :   __ Bind(&if_double);
    4398             :   {
    4399        1164 :     auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
    4400             : 
    4401         582 :     index = __ WordSar(index, one);
    4402             : 
    4403             :     // Check if field is in-object or out-of-object.
    4404         582 :     auto if_outofobject = __ MakeLabel();
    4405         582 :     __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
    4406             : 
    4407             :     // The field is located in the {object} itself.
    4408             :     {
    4409             :       Node* offset =
    4410         582 :           __ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2)),
    4411         582 :                     __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
    4412             :       if (FLAG_unbox_double_fields) {
    4413         582 :         Node* result = __ Load(MachineType::Float64(), object, offset);
    4414             :         __ Goto(&done_double, result);
    4415             :       } else {
    4416             :         Node* result = __ Load(MachineType::AnyTagged(), object, offset);
    4417             :         result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result);
    4418             :         __ Goto(&done_double, result);
    4419             :       }
    4420             :     }
    4421             : 
    4422             :     __ Bind(&if_outofobject);
    4423             :     {
    4424             :       Node* properties =
    4425         582 :           __ LoadField(AccessBuilder::ForJSObjectPropertiesOrHash(), object);
    4426             :       Node* offset =
    4427         582 :           __ IntAdd(__ WordShl(__ IntSub(zero, index),
    4428             :                                __ IntPtrConstant(kTaggedSizeLog2)),
    4429             :                     __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
    4430         582 :                                       kHeapObjectTag));
    4431         582 :       Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
    4432         582 :       result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result);
    4433             :       __ Goto(&done_double, result);
    4434             :     }
    4435             : 
    4436             :     __ Bind(&done_double);
    4437             :     {
    4438         582 :       Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
    4439             :       __ Goto(&done, result);
    4440             :     }
    4441             :   }
    4442             : 
    4443             :   __ Bind(&done);
    4444         582 :   return done.PhiAt(0);
    4445             : }
    4446             : 
    4447         464 : Node* EffectControlLinearizer::BuildReverseBytes(ExternalArrayType type,
    4448             :                                                  Node* value) {
    4449         464 :   switch (type) {
    4450             :     case kExternalInt8Array:
    4451             :     case kExternalUint8Array:
    4452             :     case kExternalUint8ClampedArray:
    4453             :       return value;
    4454             : 
    4455             :     case kExternalInt16Array: {
    4456          55 :       Node* result = __ Word32ReverseBytes(value);
    4457          55 :       result = __ Word32Sar(result, __ Int32Constant(16));
    4458          55 :       return result;
    4459             :     }
    4460             : 
    4461             :     case kExternalUint16Array: {
    4462          55 :       Node* result = __ Word32ReverseBytes(value);
    4463          55 :       result = __ Word32Shr(result, __ Int32Constant(16));
    4464          55 :       return result;
    4465             :     }
    4466             : 
    4467             :     case kExternalInt32Array:  // Fall through.
    4468             :     case kExternalUint32Array:
    4469          96 :       return __ Word32ReverseBytes(value);
    4470             : 
    4471             :     case kExternalFloat32Array: {
    4472          56 :       Node* result = __ BitcastFloat32ToInt32(value);
    4473          56 :       result = __ Word32ReverseBytes(result);
    4474          56 :       result = __ BitcastInt32ToFloat32(result);
    4475          56 :       return result;
    4476             :     }
    4477             : 
    4478             :     case kExternalFloat64Array: {
    4479          56 :       if (machine()->Is64()) {
    4480          56 :         Node* result = __ BitcastFloat64ToInt64(value);
    4481          56 :         result = __ Word64ReverseBytes(result);
    4482          56 :         result = __ BitcastInt64ToFloat64(result);
    4483          56 :         return result;
    4484             :       } else {
    4485           0 :         Node* lo = __ Word32ReverseBytes(__ Float64ExtractLowWord32(value));
    4486           0 :         Node* hi = __ Word32ReverseBytes(__ Float64ExtractHighWord32(value));
    4487           0 :         Node* result = __ Float64Constant(0.0);
    4488           0 :         result = __ Float64InsertLowWord32(result, hi);
    4489           0 :         result = __ Float64InsertHighWord32(result, lo);
    4490           0 :         return result;
    4491             :       }
    4492             :     }
    4493             : 
    4494             :     case kExternalBigInt64Array:
    4495             :     case kExternalBigUint64Array:
    4496           0 :       UNREACHABLE();
    4497             :   }
    4498           0 : }
    4499             : 
    4500         268 : Node* EffectControlLinearizer::LowerLoadDataViewElement(Node* node) {
    4501         268 :   ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
    4502             :   Node* buffer = node->InputAt(0);
    4503             :   Node* storage = node->InputAt(1);
    4504             :   Node* byte_offset = node->InputAt(2);
    4505             :   Node* index = node->InputAt(3);
    4506             :   Node* is_little_endian = node->InputAt(4);
    4507             : 
    4508             :   // We need to keep the {buffer} alive so that the GC will not release the
    4509             :   // ArrayBuffer (if there's any) as long as we are still operating on it.
    4510         268 :   __ Retain(buffer);
    4511             : 
    4512             :   // Compute the effective offset.
    4513         268 :   Node* offset = __ IntAdd(byte_offset, index);
    4514             : 
    4515             :   MachineType const machine_type =
    4516         268 :       AccessBuilder::ForTypedArrayElement(element_type, true).machine_type;
    4517             : 
    4518         268 :   Node* value = __ LoadUnaligned(machine_type, storage, offset);
    4519         268 :   auto big_endian = __ MakeLabel();
    4520         536 :   auto done = __ MakeLabel(machine_type.representation());
    4521             : 
    4522         268 :   __ GotoIfNot(is_little_endian, &big_endian);
    4523             :   {  // Little-endian load.
    4524             : #if V8_TARGET_LITTLE_ENDIAN
    4525             :     __ Goto(&done, value);
    4526             : #else
    4527             :     __ Goto(&done, BuildReverseBytes(element_type, value));
    4528             : #endif  // V8_TARGET_LITTLE_ENDIAN
    4529             :   }
    4530             : 
    4531             :   __ Bind(&big_endian);
    4532             :   {  // Big-endian load.
    4533             : #if V8_TARGET_LITTLE_ENDIAN
    4534         268 :     __ Goto(&done, BuildReverseBytes(element_type, value));
    4535             : #else
    4536             :     __ Goto(&done, value);
    4537             : #endif  // V8_TARGET_LITTLE_ENDIAN
    4538             :   }
    4539             : 
    4540             :   // We're done, return {result}.
    4541             :   __ Bind(&done);
    4542         268 :   return done.PhiAt(0);
    4543             : }
    4544             : 
    4545         572 : Node* EffectControlLinearizer::LowerLoadStackArgument(Node* node) {
    4546             :   Node* base = node->InputAt(0);
    4547             :   Node* index = node->InputAt(1);
    4548             : 
    4549             :   Node* argument =
    4550        1144 :       __ LoadElement(AccessBuilder::ForStackArgument(), base, index);
    4551             : 
    4552         572 :   return __ BitcastWordToTagged(argument);
    4553             : }
    4554             : 
    4555         196 : void EffectControlLinearizer::LowerStoreDataViewElement(Node* node) {
    4556         196 :   ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
    4557             :   Node* buffer = node->InputAt(0);
    4558             :   Node* storage = node->InputAt(1);
    4559             :   Node* byte_offset = node->InputAt(2);
    4560             :   Node* index = node->InputAt(3);
    4561             :   Node* value = node->InputAt(4);
    4562             :   Node* is_little_endian = node->InputAt(5);
    4563             : 
    4564             :   // We need to keep the {buffer} alive so that the GC will not release the
    4565             :   // ArrayBuffer (if there's any) as long as we are still operating on it.
    4566         196 :   __ Retain(buffer);
    4567             : 
    4568             :   // Compute the effective offset.
    4569         196 :   Node* offset = __ IntAdd(byte_offset, index);
    4570             : 
    4571             :   MachineType const machine_type =
    4572         196 :       AccessBuilder::ForTypedArrayElement(element_type, true).machine_type;
    4573             : 
    4574         196 :   auto big_endian = __ MakeLabel();
    4575         392 :   auto done = __ MakeLabel(machine_type.representation());
    4576             : 
    4577         196 :   __ GotoIfNot(is_little_endian, &big_endian);
    4578             :   {  // Little-endian store.
    4579             : #if V8_TARGET_LITTLE_ENDIAN
    4580             :     __ Goto(&done, value);
    4581             : #else
    4582             :     __ Goto(&done, BuildReverseBytes(element_type, value));
    4583             : #endif  // V8_TARGET_LITTLE_ENDIAN
    4584             :   }
    4585             : 
    4586             :   __ Bind(&big_endian);
    4587             :   {  // Big-endian store.
    4588             : #if V8_TARGET_LITTLE_ENDIAN
    4589         196 :     __ Goto(&done, BuildReverseBytes(element_type, value));
    4590             : #else
    4591             :     __ Goto(&done, value);
    4592             : #endif  // V8_TARGET_LITTLE_ENDIAN
    4593             :   }
    4594             : 
    4595             :   __ Bind(&done);
    4596             :   __ StoreUnaligned(machine_type.representation(), storage, offset,
    4597         196 :                     done.PhiAt(0));
    4598         196 : }
    4599             : 
    4600        4601 : Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
    4601        4601 :   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
    4602             :   Node* buffer = node->InputAt(0);
    4603             :   Node* base = node->InputAt(1);
    4604             :   Node* external = node->InputAt(2);
    4605             :   Node* index = node->InputAt(3);
    4606             : 
    4607             :   // We need to keep the {buffer} alive so that the GC will not release the
    4608             :   // ArrayBuffer (if there's any) as long as we are still operating on it.
    4609        4601 :   __ Retain(buffer);
    4610             : 
    4611             :   // Compute the effective storage pointer, handling the case where the
    4612             :   // {external} pointer is the effective storage pointer (i.e. the {base}
    4613             :   // is Smi zero).
    4614             :   Node* storage = IntPtrMatcher(base).Is(0)
    4615             :                       ? external
    4616        4601 :                       : __ UnsafePointerAdd(base, external);
    4617             : 
    4618             :   // Perform the actual typed element access.
    4619        9202 :   return __ LoadElement(AccessBuilder::ForTypedArrayElement(
    4620             :                             array_type, true, LoadSensitivity::kCritical),
    4621        9202 :                         storage, index);
    4622             : }
    4623             : 
    4624        4369 : void EffectControlLinearizer::LowerStoreTypedElement(Node* node) {
    4625        4369 :   ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
    4626             :   Node* buffer = node->InputAt(0);
    4627             :   Node* base = node->InputAt(1);
    4628             :   Node* external = node->InputAt(2);
    4629             :   Node* index = node->InputAt(3);
    4630             :   Node* value = node->InputAt(4);
    4631             : 
    4632             :   // We need to keep the {buffer} alive so that the GC will not release the
    4633             :   // ArrayBuffer (if there's any) as long as we are still operating on it.
    4634        4369 :   __ Retain(buffer);
    4635             : 
    4636             :   // Compute the effective storage pointer, handling the case where the
    4637             :   // {external} pointer is the effective storage pointer (i.e. the {base}
    4638             :   // is Smi zero).
    4639             :   Node* storage = IntPtrMatcher(base).Is(0)
    4640             :                       ? external
    4641        4369 :                       : __ UnsafePointerAdd(base, external);
    4642             : 
    4643             :   // Perform the actual typed element access.
    4644        8738 :   __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true),
    4645        4369 :                   storage, index, value);
    4646        4369 : }
    4647             : 
    4648         336 : void EffectControlLinearizer::TransitionElementsTo(Node* node, Node* array,
    4649             :                                                    ElementsKind from,
    4650             :                                                    ElementsKind to) {
    4651             :   DCHECK(IsMoreGeneralElementsKindTransition(from, to));
    4652             :   DCHECK(to == HOLEY_ELEMENTS || to == HOLEY_DOUBLE_ELEMENTS);
    4653             : 
    4654             :   Handle<Map> target(to == HOLEY_ELEMENTS ? FastMapParameterOf(node->op())
    4655         336 :                                           : DoubleMapParameterOf(node->op()));
    4656         336 :   Node* target_map = __ HeapConstant(target);
    4657             : 
    4658         336 :   if (IsSimpleMapChangeTransition(from, to)) {
    4659         111 :     __ StoreField(AccessBuilder::ForMap(), array, target_map);
    4660             :   } else {
    4661             :     // Instance migration, call out to the runtime for {array}.
    4662         225 :     Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    4663             :     Runtime::FunctionId id = Runtime::kTransitionElementsKind;
    4664         225 :     auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    4665         225 :         graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
    4666         225 :     __ Call(call_descriptor, __ CEntryStubConstant(1), array, target_map,
    4667             :             __ ExternalConstant(ExternalReference::Create(id)),
    4668         225 :             __ Int32Constant(2), __ NoContextConstant());
    4669             :   }
    4670         336 : }
    4671             : 
    4672           0 : Node* EffectControlLinearizer::IsElementsKindGreaterThan(
    4673             :     Node* kind, ElementsKind reference_kind) {
    4674         406 :   Node* ref_kind = __ Int32Constant(reference_kind);
    4675         406 :   Node* ret = __ Int32LessThan(ref_kind, kind);
    4676           0 :   return ret;
    4677             : }
    4678             : 
    4679          86 : void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
    4680             :   Node* array = node->InputAt(0);
    4681             :   Node* index = node->InputAt(1);
    4682             :   Node* value = node->InputAt(2);
    4683             : 
    4684             :   // Possibly transition array based on input and store.
    4685             :   //
    4686             :   //   -- TRANSITION PHASE -----------------
    4687             :   //   kind = ElementsKind(array)
    4688             :   //   if value is not smi {
    4689             :   //     if kind == HOLEY_SMI_ELEMENTS {
    4690             :   //       if value is heap number {
    4691             :   //         Transition array to HOLEY_DOUBLE_ELEMENTS
    4692             :   //         kind = HOLEY_DOUBLE_ELEMENTS
    4693             :   //       } else {
    4694             :   //         Transition array to HOLEY_ELEMENTS
    4695             :   //         kind = HOLEY_ELEMENTS
    4696             :   //       }
    4697             :   //     } else if kind == HOLEY_DOUBLE_ELEMENTS {
    4698             :   //       if value is not heap number {
    4699             :   //         Transition array to HOLEY_ELEMENTS
    4700             :   //         kind = HOLEY_ELEMENTS
    4701             :   //       }
    4702             :   //     }
    4703             :   //   }
    4704             :   //
    4705             :   //   -- STORE PHASE ----------------------
    4706             :   //   [make sure {kind} is up-to-date]
    4707             :   //   if kind == HOLEY_DOUBLE_ELEMENTS {
    4708             :   //     if value is smi {
    4709             :   //       float_value = convert smi to float
    4710             :   //       Store array[index] = float_value
    4711             :   //     } else {
    4712             :   //       float_value = value
    4713             :   //       Store array[index] = float_value
    4714             :   //     }
    4715             :   //   } else {
    4716             :   //     // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
    4717             :   //     Store array[index] = value
    4718             :   //   }
    4719             :   //
    4720         172 :   Node* map = __ LoadField(AccessBuilder::ForMap(), array);
    4721             :   Node* kind;
    4722             :   {
    4723          86 :     Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
    4724          86 :     Node* mask = __ Int32Constant(Map::ElementsKindBits::kMask);
    4725          86 :     Node* andit = __ Word32And(bit_field2, mask);
    4726          86 :     Node* shift = __ Int32Constant(Map::ElementsKindBits::kShift);
    4727          86 :     kind = __ Word32Shr(andit, shift);
    4728             :   }
    4729             : 
    4730         172 :   auto do_store = __ MakeLabel(MachineRepresentation::kWord32);
    4731             :   // We can store a smi anywhere.
    4732          86 :   __ GotoIf(ObjectIsSmi(value), &do_store, kind);
    4733             : 
    4734             :   // {value} is a HeapObject.
    4735          86 :   auto transition_smi_array = __ MakeDeferredLabel();
    4736          86 :   auto transition_double_to_fast = __ MakeDeferredLabel();
    4737             :   {
    4738             :     __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
    4739          86 :                  &transition_smi_array);
    4740             :     __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS), &do_store,
    4741          86 :                  kind);
    4742             : 
    4743             :     // We have double elements kind. Only a HeapNumber can be stored
    4744             :     // without effecting a transition.
    4745          86 :     Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    4746          86 :     Node* heap_number_map = __ HeapNumberMapConstant();
    4747          86 :     Node* check = __ WordEqual(value_map, heap_number_map);
    4748          86 :     __ GotoIfNot(check, &transition_double_to_fast);
    4749             :     __ Goto(&do_store, kind);
    4750             :   }
    4751             : 
    4752             :   __ Bind(&transition_smi_array);  // deferred code.
    4753             :   {
    4754             :     // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_DOUBLE_ELEMENTS or
    4755             :     // to HOLEY_ELEMENTS.
    4756          86 :     auto if_value_not_heap_number = __ MakeLabel();
    4757          86 :     Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    4758          86 :     Node* heap_number_map = __ HeapNumberMapConstant();
    4759          86 :     Node* check = __ WordEqual(value_map, heap_number_map);
    4760          86 :     __ GotoIfNot(check, &if_value_not_heap_number);
    4761             :     {
    4762             :       // {value} is a HeapNumber.
    4763             :       TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS,
    4764          86 :                            HOLEY_DOUBLE_ELEMENTS);
    4765          86 :       __ Goto(&do_store, __ Int32Constant(HOLEY_DOUBLE_ELEMENTS));
    4766             :     }
    4767             :     __ Bind(&if_value_not_heap_number);
    4768             :     {
    4769          86 :       TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS);
    4770          86 :       __ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
    4771             :     }
    4772             :   }
    4773             : 
    4774             :   __ Bind(&transition_double_to_fast);  // deferred code.
    4775             :   {
    4776          86 :     TransitionElementsTo(node, array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS);
    4777          86 :     __ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
    4778             :   }
    4779             : 
    4780             :   // Make sure kind is up-to-date.
    4781             :   __ Bind(&do_store);
    4782             :   kind = do_store.PhiAt(0);
    4783             : 
    4784          86 :   Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
    4785          86 :   auto if_kind_is_double = __ MakeLabel();
    4786          86 :   auto done = __ MakeLabel();
    4787             :   __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
    4788          86 :             &if_kind_is_double);
    4789             :   {
    4790             :     // Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
    4791         172 :     __ StoreElement(AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS),
    4792          86 :                     elements, index, value);
    4793             :     __ Goto(&done);
    4794             :   }
    4795             :   __ Bind(&if_kind_is_double);
    4796             :   {
    4797             :     // Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
    4798          86 :     auto do_double_store = __ MakeLabel();
    4799          86 :     __ GotoIfNot(ObjectIsSmi(value), &do_double_store);
    4800             :     {
    4801          86 :       Node* int_value = ChangeSmiToInt32(value);
    4802          86 :       Node* float_value = __ ChangeInt32ToFloat64(int_value);
    4803         172 :       __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
    4804          86 :                       index, float_value);
    4805             :       __ Goto(&done);
    4806             :     }
    4807             :     __ Bind(&do_double_store);
    4808             :     {
    4809             :       Node* float_value =
    4810          86 :           __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
    4811         172 :       __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
    4812          86 :                       index, __ Float64SilenceNaN(float_value));
    4813             :       __ Goto(&done);
    4814             :     }
    4815             :   }
    4816             : 
    4817             :   __ Bind(&done);
    4818          86 : }
    4819             : 
    4820          28 : void EffectControlLinearizer::LowerTransitionAndStoreNumberElement(Node* node) {
    4821             :   Node* array = node->InputAt(0);
    4822             :   Node* index = node->InputAt(1);
    4823             :   Node* value = node->InputAt(2);  // This is a Float64, not tagged.
    4824             : 
    4825             :   // Possibly transition array based on input and store.
    4826             :   //
    4827             :   //   -- TRANSITION PHASE -----------------
    4828             :   //   kind = ElementsKind(array)
    4829             :   //   if kind == HOLEY_SMI_ELEMENTS {
    4830             :   //     Transition array to HOLEY_DOUBLE_ELEMENTS
    4831             :   //   } else if kind != HOLEY_DOUBLE_ELEMENTS {
    4832             :   //     This is UNREACHABLE, execute a debug break.
    4833             :   //   }
    4834             :   //
    4835             :   //   -- STORE PHASE ----------------------
    4836             :   //   Store array[index] = value (it's a float)
    4837             :   //
    4838          56 :   Node* map = __ LoadField(AccessBuilder::ForMap(), array);
    4839             :   Node* kind;
    4840             :   {
    4841          28 :     Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
    4842          28 :     Node* mask = __ Int32Constant(Map::ElementsKindBits::kMask);
    4843          28 :     Node* andit = __ Word32And(bit_field2, mask);
    4844          28 :     Node* shift = __ Int32Constant(Map::ElementsKindBits::kShift);
    4845          28 :     kind = __ Word32Shr(andit, shift);
    4846             :   }
    4847             : 
    4848          28 :   auto do_store = __ MakeLabel();
    4849             : 
    4850             :   // {value} is a float64.
    4851          28 :   auto transition_smi_array = __ MakeDeferredLabel();
    4852             :   {
    4853             :     __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
    4854          28 :                  &transition_smi_array);
    4855             :     // We expect that our input array started at HOLEY_SMI_ELEMENTS, and
    4856             :     // climbs the lattice up to HOLEY_DOUBLE_ELEMENTS. Force a debug break
    4857             :     // if this assumption is broken. It also would be the case that
    4858             :     // loop peeling can break this assumption.
    4859          28 :     __ GotoIf(__ Word32Equal(kind, __ Int32Constant(HOLEY_DOUBLE_ELEMENTS)),
    4860          28 :               &do_store);
    4861             :     // TODO(turbofan): It would be good to have an "Unreachable()" node type.
    4862          28 :     __ DebugBreak();
    4863             :     __ Goto(&do_store);
    4864             :   }
    4865             : 
    4866             :   __ Bind(&transition_smi_array);  // deferred code.
    4867             :   {
    4868             :     // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_DOUBLE_ELEMENTS.
    4869             :     TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS,
    4870          28 :                          HOLEY_DOUBLE_ELEMENTS);
    4871             :     __ Goto(&do_store);
    4872             :   }
    4873             : 
    4874             :   __ Bind(&do_store);
    4875             : 
    4876          28 :   Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
    4877          56 :   __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements, index,
    4878          28 :                   __ Float64SilenceNaN(value));
    4879          28 : }
    4880             : 
    4881          25 : void EffectControlLinearizer::LowerTransitionAndStoreNonNumberElement(
    4882             :     Node* node) {
    4883             :   Node* array = node->InputAt(0);
    4884             :   Node* index = node->InputAt(1);
    4885             :   Node* value = node->InputAt(2);
    4886             : 
    4887             :   // Possibly transition array based on input and store.
    4888             :   //
    4889             :   //   -- TRANSITION PHASE -----------------
    4890             :   //   kind = ElementsKind(array)
    4891             :   //   if kind == HOLEY_SMI_ELEMENTS {
    4892             :   //     Transition array to HOLEY_ELEMENTS
    4893             :   //   } else if kind == HOLEY_DOUBLE_ELEMENTS {
    4894             :   //     Transition array to HOLEY_ELEMENTS
    4895             :   //   }
    4896             :   //
    4897             :   //   -- STORE PHASE ----------------------
    4898             :   //   // kind is HOLEY_ELEMENTS
    4899             :   //   Store array[index] = value
    4900             :   //
    4901          50 :   Node* map = __ LoadField(AccessBuilder::ForMap(), array);
    4902             :   Node* kind;
    4903             :   {
    4904          25 :     Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
    4905          25 :     Node* mask = __ Int32Constant(Map::ElementsKindBits::kMask);
    4906          25 :     Node* andit = __ Word32And(bit_field2, mask);
    4907          25 :     Node* shift = __ Int32Constant(Map::ElementsKindBits::kShift);
    4908          25 :     kind = __ Word32Shr(andit, shift);
    4909             :   }
    4910             : 
    4911          25 :   auto do_store = __ MakeLabel();
    4912             : 
    4913          25 :   auto transition_smi_array = __ MakeDeferredLabel();
    4914          25 :   auto transition_double_to_fast = __ MakeDeferredLabel();
    4915             :   {
    4916             :     __ GotoIfNot(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
    4917          25 :                  &transition_smi_array);
    4918             :     __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
    4919          25 :               &transition_double_to_fast);
    4920             :     __ Goto(&do_store);
    4921             :   }
    4922             : 
    4923             :   __ Bind(&transition_smi_array);  // deferred code.
    4924             :   {
    4925             :     // Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_ELEMENTS.
    4926          25 :     TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS);
    4927             :     __ Goto(&do_store);
    4928             :   }
    4929             : 
    4930             :   __ Bind(&transition_double_to_fast);  // deferred code.
    4931             :   {
    4932          25 :     TransitionElementsTo(node, array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS);
    4933             :     __ Goto(&do_store);
    4934             :   }
    4935             : 
    4936             :   __ Bind(&do_store);
    4937             : 
    4938          25 :   Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
    4939             :   // Our ElementsKind is HOLEY_ELEMENTS.
    4940          25 :   ElementAccess access = AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS);
    4941          25 :   Type value_type = ValueTypeParameterOf(node->op());
    4942          25 :   if (value_type.Is(Type::BooleanOrNullOrUndefined())) {
    4943          16 :     access.type = value_type;
    4944          16 :     access.write_barrier_kind = kNoWriteBarrier;
    4945             :   }
    4946          25 :   __ StoreElement(access, elements, index, value);
    4947          25 : }
    4948             : 
    4949          70 : void EffectControlLinearizer::LowerStoreSignedSmallElement(Node* node) {
    4950             :   Node* array = node->InputAt(0);
    4951             :   Node* index = node->InputAt(1);
    4952             :   Node* value = node->InputAt(2);  // int32
    4953             : 
    4954             :   // Store a signed small in an output array.
    4955             :   //
    4956             :   //   kind = ElementsKind(array)
    4957             :   //
    4958             :   //   -- STORE PHASE ----------------------
    4959             :   //   if kind == HOLEY_DOUBLE_ELEMENTS {
    4960             :   //     float_value = convert int32 to float
    4961             :   //     Store array[index] = float_value
    4962             :   //   } else {
    4963             :   //     // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
    4964             :   //     smi_value = convert int32 to smi
    4965             :   //     Store array[index] = smi_value
    4966             :   //   }
    4967             :   //
    4968         140 :   Node* map = __ LoadField(AccessBuilder::ForMap(), array);
    4969             :   Node* kind;
    4970             :   {
    4971          70 :     Node* bit_field2 = __ LoadField(AccessBuilder::ForMapBitField2(), map);
    4972          70 :     Node* mask = __ Int32Constant(Map::ElementsKindBits::kMask);
    4973          70 :     Node* andit = __ Word32And(bit_field2, mask);
    4974          70 :     Node* shift = __ Int32Constant(Map::ElementsKindBits::kShift);
    4975          70 :     kind = __ Word32Shr(andit, shift);
    4976             :   }
    4977             : 
    4978          70 :   Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
    4979          70 :   auto if_kind_is_double = __ MakeLabel();
    4980          70 :   auto done = __ MakeLabel();
    4981             :   __ GotoIf(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS),
    4982          70 :             &if_kind_is_double);
    4983             :   {
    4984             :     // Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
    4985             :     // In this case, we know our value is a signed small, and we can optimize
    4986             :     // the ElementAccess information.
    4987          70 :     ElementAccess access = AccessBuilder::ForFixedArrayElement();
    4988          70 :     access.type = Type::SignedSmall();
    4989          70 :     access.machine_type = MachineType::TaggedSigned();
    4990          70 :     access.write_barrier_kind = kNoWriteBarrier;
    4991          70 :     Node* smi_value = ChangeInt32ToSmi(value);
    4992          70 :     __ StoreElement(access, elements, index, smi_value);
    4993             :     __ Goto(&done);
    4994             :   }
    4995             :   __ Bind(&if_kind_is_double);
    4996             :   {
    4997             :     // Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
    4998          70 :     Node* float_value = __ ChangeInt32ToFloat64(value);
    4999         140 :     __ StoreElement(AccessBuilder::ForFixedDoubleArrayElement(), elements,
    5000          70 :                     index, float_value);
    5001             :     __ Goto(&done);
    5002             :   }
    5003             : 
    5004             :   __ Bind(&done);
    5005          70 : }
    5006             : 
    5007        2468 : void EffectControlLinearizer::LowerRuntimeAbort(Node* node) {
    5008        2468 :   AbortReason reason = AbortReasonOf(node->op());
    5009        2468 :   Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    5010             :   Runtime::FunctionId id = Runtime::kAbort;
    5011        2468 :   auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    5012        2468 :       graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
    5013        4936 :   __ Call(call_descriptor, __ CEntryStubConstant(1),
    5014             :           jsgraph()->SmiConstant(static_cast<int>(reason)),
    5015             :           __ ExternalConstant(ExternalReference::Create(id)),
    5016        2468 :           __ Int32Constant(1), __ NoContextConstant());
    5017        2468 : }
    5018             : 
    5019         873 : Node* EffectControlLinearizer::LowerConvertReceiver(Node* node) {
    5020         873 :   ConvertReceiverMode const mode = ConvertReceiverModeOf(node->op());
    5021             :   Node* value = node->InputAt(0);
    5022             :   Node* global_proxy = node->InputAt(1);
    5023             : 
    5024         873 :   switch (mode) {
    5025             :     case ConvertReceiverMode::kNullOrUndefined: {
    5026             :       return global_proxy;
    5027             :     }
    5028             :     case ConvertReceiverMode::kNotNullOrUndefined: {
    5029         806 :       auto convert_to_object = __ MakeDeferredLabel();
    5030        1612 :       auto done_convert = __ MakeLabel(MachineRepresentation::kTagged);
    5031             : 
    5032             :       // Check if {value} is already a JSReceiver.
    5033        1612 :       __ GotoIf(ObjectIsSmi(value), &convert_to_object);
    5034             :       STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    5035         806 :       Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    5036             :       Node* value_instance_type =
    5037         806 :           __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    5038         806 :       Node* check = __ Uint32LessThan(
    5039         806 :           value_instance_type, __ Uint32Constant(FIRST_JS_RECEIVER_TYPE));
    5040         806 :       __ GotoIf(check, &convert_to_object);
    5041             :       __ Goto(&done_convert, value);
    5042             : 
    5043             :       // Wrap the primitive {value} into a JSValue.
    5044             :       __ Bind(&convert_to_object);
    5045             :       Operator::Properties properties = Operator::kEliminatable;
    5046         806 :       Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
    5047             :       CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    5048             :       auto call_descriptor = Linkage::GetStubCallDescriptor(
    5049         806 :           graph()->zone(), callable.descriptor(),
    5050         806 :           callable.descriptor().GetStackParameterCount(), flags, properties);
    5051             :       Node* native_context = __ LoadField(
    5052         806 :           AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
    5053        1612 :       Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
    5054         806 :                              value, native_context);
    5055             :       __ Goto(&done_convert, result);
    5056             : 
    5057             :       __ Bind(&done_convert);
    5058             :       return done_convert.PhiAt(0);
    5059             :     }
    5060             :     case ConvertReceiverMode::kAny: {
    5061          67 :       auto convert_to_object = __ MakeDeferredLabel();
    5062          67 :       auto convert_global_proxy = __ MakeDeferredLabel();
    5063         134 :       auto done_convert = __ MakeLabel(MachineRepresentation::kTagged);
    5064             : 
    5065             :       // Check if {value} is already a JSReceiver, or null/undefined.
    5066         134 :       __ GotoIf(ObjectIsSmi(value), &convert_to_object);
    5067             :       STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
    5068          67 :       Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
    5069             :       Node* value_instance_type =
    5070          67 :           __ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
    5071          67 :       Node* check = __ Uint32LessThan(
    5072          67 :           value_instance_type, __ Uint32Constant(FIRST_JS_RECEIVER_TYPE));
    5073          67 :       __ GotoIf(check, &convert_to_object);
    5074             :       __ Goto(&done_convert, value);
    5075             : 
    5076             :       // Wrap the primitive {value} into a JSValue.
    5077             :       __ Bind(&convert_to_object);
    5078          67 :       __ GotoIf(__ WordEqual(value, __ UndefinedConstant()),
    5079          67 :                 &convert_global_proxy);
    5080          67 :       __ GotoIf(__ WordEqual(value, __ NullConstant()), &convert_global_proxy);
    5081             :       Operator::Properties properties = Operator::kEliminatable;
    5082          67 :       Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
    5083             :       CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    5084             :       auto call_descriptor = Linkage::GetStubCallDescriptor(
    5085          67 :           graph()->zone(), callable.descriptor(),
    5086          67 :           callable.descriptor().GetStackParameterCount(), flags, properties);
    5087             :       Node* native_context = __ LoadField(
    5088          67 :           AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
    5089         134 :       Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
    5090          67 :                              value, native_context);
    5091             :       __ Goto(&done_convert, result);
    5092             : 
    5093             :       // Replace the {value} with the {global_proxy}.
    5094             :       __ Bind(&convert_global_proxy);
    5095             :       __ Goto(&done_convert, global_proxy);
    5096             : 
    5097             :       __ Bind(&done_convert);
    5098             :       return done_convert.PhiAt(0);
    5099             :     }
    5100             :   }
    5101             : 
    5102           0 :   UNREACHABLE();
    5103             :   return nullptr;
    5104             : }
    5105             : 
    5106        8230 : Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundUp(Node* node) {
    5107             :   // Nothing to be done if a fast hardware instruction is available.
    5108        8230 :   if (machine()->Float64RoundUp().IsSupported()) {
    5109             :     return Nothing<Node*>();
    5110             :   }
    5111             : 
    5112             :   Node* const input = node->InputAt(0);
    5113             : 
    5114             :   // General case for ceil.
    5115             :   //
    5116             :   //   if 0.0 < input then
    5117             :   //     if 2^52 <= input then
    5118             :   //       input
    5119             :   //     else
    5120             :   //       let temp1 = (2^52 + input) - 2^52 in
    5121             :   //       if temp1 < input then
    5122             :   //         temp1 + 1
    5123             :   //       else
    5124             :   //         temp1
    5125             :   //   else
    5126             :   //     if input == 0 then
    5127             :   //       input
    5128             :   //     else
    5129             :   //       if input <= -2^52 then
    5130             :   //         input
    5131             :   //       else
    5132             :   //         let temp1 = -0 - input in
    5133             :   //         let temp2 = (2^52 + temp1) - 2^52 in
    5134             :   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
    5135             :   //         -0 - temp3
    5136             : 
    5137           0 :   auto if_not_positive = __ MakeDeferredLabel();
    5138           0 :   auto if_greater_than_two_52 = __ MakeDeferredLabel();
    5139           0 :   auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
    5140           0 :   auto if_zero = __ MakeDeferredLabel();
    5141           0 :   auto done_temp3 = __ MakeLabel(MachineRepresentation::kFloat64);
    5142           0 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    5143             : 
    5144           0 :   Node* const zero = __ Float64Constant(0.0);
    5145           0 :   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
    5146           0 :   Node* const one = __ Float64Constant(1.0);
    5147             : 
    5148           0 :   Node* check0 = __ Float64LessThan(zero, input);
    5149           0 :   __ GotoIfNot(check0, &if_not_positive);
    5150             :   {
    5151           0 :     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
    5152           0 :     __ GotoIf(check1, &if_greater_than_two_52);
    5153             :     {
    5154           0 :       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
    5155           0 :       __ GotoIfNot(__ Float64LessThan(temp1, input), &done, temp1);
    5156           0 :       __ Goto(&done, __ Float64Add(temp1, one));
    5157             :     }
    5158             : 
    5159             :     __ Bind(&if_greater_than_two_52);
    5160             :     __ Goto(&done, input);
    5161             :   }
    5162             : 
    5163             :   __ Bind(&if_not_positive);
    5164             :   {
    5165           0 :     Node* check1 = __ Float64Equal(input, zero);
    5166           0 :     __ GotoIf(check1, &if_zero);
    5167             : 
    5168           0 :     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
    5169           0 :     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
    5170           0 :     __ GotoIf(check2, &if_less_than_minus_two_52);
    5171             : 
    5172             :     {
    5173           0 :       Node* const minus_zero = __ Float64Constant(-0.0);
    5174           0 :       Node* temp1 = __ Float64Sub(minus_zero, input);
    5175           0 :       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
    5176           0 :       Node* check3 = __ Float64LessThan(temp1, temp2);
    5177           0 :       __ GotoIfNot(check3, &done_temp3, temp2);
    5178           0 :       __ Goto(&done_temp3, __ Float64Sub(temp2, one));
    5179             : 
    5180             :       __ Bind(&done_temp3);
    5181             :       Node* temp3 = done_temp3.PhiAt(0);
    5182           0 :       __ Goto(&done, __ Float64Sub(minus_zero, temp3));
    5183             :     }
    5184             :     __ Bind(&if_less_than_minus_two_52);
    5185             :     __ Goto(&done, input);
    5186             : 
    5187             :     __ Bind(&if_zero);
    5188             :     __ Goto(&done, input);
    5189             :   }
    5190             :   __ Bind(&done);
    5191             :   return Just(done.PhiAt(0));
    5192             : }
    5193             : 
    5194           0 : Node* EffectControlLinearizer::BuildFloat64RoundDown(Node* value) {
    5195           0 :   if (machine()->Float64RoundDown().IsSupported()) {
    5196           0 :     return __ Float64RoundDown(value);
    5197             :   }
    5198             : 
    5199             :   Node* const input = value;
    5200             : 
    5201             :   // General case for floor.
    5202             :   //
    5203             :   //   if 0.0 < input then
    5204             :   //     if 2^52 <= input then
    5205             :   //       input
    5206             :   //     else
    5207             :   //       let temp1 = (2^52 + input) - 2^52 in
    5208             :   //       if input < temp1 then
    5209             :   //         temp1 - 1
    5210             :   //       else
    5211             :   //         temp1
    5212             :   //   else
    5213             :   //     if input == 0 then
    5214             :   //       input
    5215             :   //     else
    5216             :   //       if input <= -2^52 then
    5217             :   //         input
    5218             :   //       else
    5219             :   //         let temp1 = -0 - input in
    5220             :   //         let temp2 = (2^52 + temp1) - 2^52 in
    5221             :   //         if temp2 < temp1 then
    5222             :   //           -1 - temp2
    5223             :   //         else
    5224             :   //           -0 - temp2
    5225             : 
    5226           0 :   auto if_not_positive = __ MakeDeferredLabel();
    5227           0 :   auto if_greater_than_two_52 = __ MakeDeferredLabel();
    5228           0 :   auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
    5229           0 :   auto if_temp2_lt_temp1 = __ MakeLabel();
    5230           0 :   auto if_zero = __ MakeDeferredLabel();
    5231           0 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    5232             : 
    5233           0 :   Node* const zero = __ Float64Constant(0.0);
    5234           0 :   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
    5235             : 
    5236           0 :   Node* check0 = __ Float64LessThan(zero, input);
    5237           0 :   __ GotoIfNot(check0, &if_not_positive);
    5238             :   {
    5239           0 :     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
    5240           0 :     __ GotoIf(check1, &if_greater_than_two_52);
    5241             :     {
    5242           0 :       Node* const one = __ Float64Constant(1.0);
    5243           0 :       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
    5244           0 :       __ GotoIfNot(__ Float64LessThan(input, temp1), &done, temp1);
    5245           0 :       __ Goto(&done, __ Float64Sub(temp1, one));
    5246             :     }
    5247             : 
    5248             :     __ Bind(&if_greater_than_two_52);
    5249             :     __ Goto(&done, input);
    5250             :   }
    5251             : 
    5252             :   __ Bind(&if_not_positive);
    5253             :   {
    5254           0 :     Node* check1 = __ Float64Equal(input, zero);
    5255           0 :     __ GotoIf(check1, &if_zero);
    5256             : 
    5257           0 :     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
    5258           0 :     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
    5259           0 :     __ GotoIf(check2, &if_less_than_minus_two_52);
    5260             : 
    5261             :     {
    5262           0 :       Node* const minus_zero = __ Float64Constant(-0.0);
    5263           0 :       Node* temp1 = __ Float64Sub(minus_zero, input);
    5264           0 :       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
    5265           0 :       Node* check3 = __ Float64LessThan(temp2, temp1);
    5266           0 :       __ GotoIf(check3, &if_temp2_lt_temp1);
    5267           0 :       __ Goto(&done, __ Float64Sub(minus_zero, temp2));
    5268             : 
    5269             :       __ Bind(&if_temp2_lt_temp1);
    5270           0 :       __ Goto(&done, __ Float64Sub(__ Float64Constant(-1.0), temp2));
    5271             :     }
    5272             :     __ Bind(&if_less_than_minus_two_52);
    5273             :     __ Goto(&done, input);
    5274             : 
    5275             :     __ Bind(&if_zero);
    5276             :     __ Goto(&done, input);
    5277             :   }
    5278             :   __ Bind(&done);
    5279             :   return done.PhiAt(0);
    5280             : }
    5281             : 
    5282       26794 : Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundDown(Node* node) {
    5283             :   // Nothing to be done if a fast hardware instruction is available.
    5284       26794 :   if (machine()->Float64RoundDown().IsSupported()) {
    5285             :     return Nothing<Node*>();
    5286             :   }
    5287             : 
    5288             :   Node* const input = node->InputAt(0);
    5289           0 :   return Just(BuildFloat64RoundDown(input));
    5290             : }
    5291             : 
    5292         266 : Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node) {
    5293             :   // Nothing to be done if a fast hardware instruction is available.
    5294         266 :   if (machine()->Float64RoundTiesEven().IsSupported()) {
    5295             :     return Nothing<Node*>();
    5296             :   }
    5297             : 
    5298             :   Node* const input = node->InputAt(0);
    5299             : 
    5300             :   // Generate case for round ties to even:
    5301             :   //
    5302             :   //   let value = floor(input) in
    5303             :   //   let temp1 = input - value in
    5304             :   //   if temp1 < 0.5 then
    5305             :   //     value
    5306             :   //   else if 0.5 < temp1 then
    5307             :   //     value + 1.0
    5308             :   //   else
    5309             :   //     let temp2 = value % 2.0 in
    5310             :   //     if temp2 == 0.0 then
    5311             :   //       value
    5312             :   //     else
    5313             :   //       value + 1.0
    5314             : 
    5315           0 :   auto if_is_half = __ MakeLabel();
    5316           0 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    5317             : 
    5318           0 :   Node* value = BuildFloat64RoundDown(input);
    5319           0 :   Node* temp1 = __ Float64Sub(input, value);
    5320             : 
    5321           0 :   Node* const half = __ Float64Constant(0.5);
    5322           0 :   Node* check0 = __ Float64LessThan(temp1, half);
    5323           0 :   __ GotoIf(check0, &done, value);
    5324             : 
    5325           0 :   Node* const one = __ Float64Constant(1.0);
    5326           0 :   Node* check1 = __ Float64LessThan(half, temp1);
    5327           0 :   __ GotoIfNot(check1, &if_is_half);
    5328           0 :   __ Goto(&done, __ Float64Add(value, one));
    5329             : 
    5330             :   __ Bind(&if_is_half);
    5331           0 :   Node* temp2 = __ Float64Mod(value, __ Float64Constant(2.0));
    5332           0 :   Node* check2 = __ Float64Equal(temp2, __ Float64Constant(0.0));
    5333           0 :   __ GotoIf(check2, &done, value);
    5334           0 :   __ Goto(&done, __ Float64Add(value, one));
    5335             : 
    5336             :   __ Bind(&done);
    5337             :   return Just(done.PhiAt(0));
    5338             : }
    5339             : 
    5340         140 : Node* EffectControlLinearizer::BuildFloat64RoundTruncate(Node* input) {
    5341         140 :   if (machine()->Float64RoundTruncate().IsSupported()) {
    5342         140 :     return __ Float64RoundTruncate(input);
    5343             :   }
    5344             :   // General case for trunc.
    5345             :   //
    5346             :   //   if 0.0 < input then
    5347             :   //     if 2^52 <= input then
    5348             :   //       input
    5349             :   //     else
    5350             :   //       let temp1 = (2^52 + input) - 2^52 in
    5351             :   //       if input < temp1 then
    5352             :   //         temp1 - 1
    5353             :   //       else
    5354             :   //         temp1
    5355             :   //   else
    5356             :   //     if input == 0 then
    5357             :   //       input
    5358             :   //     else
    5359             :   //       if input <= -2^52 then
    5360             :   //         input
    5361             :   //       else
    5362             :   //         let temp1 = -0 - input in
    5363             :   //         let temp2 = (2^52 + temp1) - 2^52 in
    5364             :   //         let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
    5365             :   //         -0 - temp3
    5366             :   //
    5367             :   // Note: We do not use the Diamond helper class here, because it really hurts
    5368             :   // readability with nested diamonds.
    5369             : 
    5370           0 :   auto if_not_positive = __ MakeDeferredLabel();
    5371           0 :   auto if_greater_than_two_52 = __ MakeDeferredLabel();
    5372           0 :   auto if_less_than_minus_two_52 = __ MakeDeferredLabel();
    5373           0 :   auto if_zero = __ MakeDeferredLabel();
    5374           0 :   auto done_temp3 = __ MakeLabel(MachineRepresentation::kFloat64);
    5375           0 :   auto done = __ MakeLabel(MachineRepresentation::kFloat64);
    5376             : 
    5377           0 :   Node* const zero = __ Float64Constant(0.0);
    5378           0 :   Node* const two_52 = __ Float64Constant(4503599627370496.0E0);
    5379           0 :   Node* const one = __ Float64Constant(1.0);
    5380             : 
    5381           0 :   Node* check0 = __ Float64LessThan(zero, input);
    5382           0 :   __ GotoIfNot(check0, &if_not_positive);
    5383             :   {
    5384           0 :     Node* check1 = __ Float64LessThanOrEqual(two_52, input);
    5385           0 :     __ GotoIf(check1, &if_greater_than_two_52);
    5386             :     {
    5387           0 :       Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52);
    5388           0 :       __ GotoIfNot(__ Float64LessThan(input, temp1), &done, temp1);
    5389           0 :       __ Goto(&done, __ Float64Sub(temp1, one));
    5390             :     }
    5391             : 
    5392             :     __ Bind(&if_greater_than_two_52);
    5393             :     __ Goto(&done, input);
    5394             :   }
    5395             : 
    5396             :   __ Bind(&if_not_positive);
    5397             :   {
    5398           0 :     Node* check1 = __ Float64Equal(input, zero);
    5399           0 :     __ GotoIf(check1, &if_zero);
    5400             : 
    5401           0 :     Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0);
    5402           0 :     Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52);
    5403           0 :     __ GotoIf(check2, &if_less_than_minus_two_52);
    5404             : 
    5405             :     {
    5406           0 :       Node* const minus_zero = __ Float64Constant(-0.0);
    5407           0 :       Node* temp1 = __ Float64Sub(minus_zero, input);
    5408           0 :       Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52);
    5409           0 :       Node* check3 = __ Float64LessThan(temp1, temp2);
    5410           0 :       __ GotoIfNot(check3, &done_temp3, temp2);
    5411           0 :       __ Goto(&done_temp3, __ Float64Sub(temp2, one));
    5412             : 
    5413             :       __ Bind(&done_temp3);
    5414             :       Node* temp3 = done_temp3.PhiAt(0);
    5415           0 :       __ Goto(&done, __ Float64Sub(minus_zero, temp3));
    5416             :     }
    5417             :     __ Bind(&if_less_than_minus_two_52);
    5418             :     __ Goto(&done, input);
    5419             : 
    5420             :     __ Bind(&if_zero);
    5421             :     __ Goto(&done, input);
    5422             :   }
    5423             :   __ Bind(&done);
    5424             :   return done.PhiAt(0);
    5425             : }
    5426             : 
    5427        6914 : Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
    5428             :   // Nothing to be done if a fast hardware instruction is available.
    5429        6914 :   if (machine()->Float64RoundTruncate().IsSupported()) {
    5430             :     return Nothing<Node*>();
    5431             :   }
    5432             : 
    5433             :   Node* const input = node->InputAt(0);
    5434           0 :   return Just(BuildFloat64RoundTruncate(input));
    5435             : }
    5436             : 
    5437         162 : Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
    5438         162 :   Node* table = NodeProperties::GetValueInput(node, 0);
    5439         162 :   Node* key = NodeProperties::GetValueInput(node, 1);
    5440             : 
    5441             :   {
    5442             :     Callable const callable =
    5443         162 :         Builtins::CallableFor(isolate(), Builtins::kFindOrderedHashMapEntry);
    5444         162 :     Operator::Properties const properties = node->op()->properties();
    5445             :     CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
    5446             :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    5447         162 :         graph()->zone(), callable.descriptor(),
    5448         162 :         callable.descriptor().GetStackParameterCount(), flags, properties);
    5449         486 :     return __ Call(call_descriptor, __ HeapConstant(callable.code()), table,
    5450         324 :                    key, __ NoContextConstant());
    5451             :   }
    5452             : }
    5453             : 
    5454          16 : Node* EffectControlLinearizer::ComputeUnseededHash(Node* value) {
    5455             :   // See v8::internal::ComputeUnseededHash()
    5456          16 :   value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xFFFFFFFF)),
    5457          16 :                       __ Word32Shl(value, __ Int32Constant(15)));
    5458          16 :   value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
    5459          16 :   value = __ Int32Add(value, __ Word32Shl(value, __ Int32Constant(2)));
    5460          16 :   value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(4)));
    5461          16 :   value = __ Int32Mul(value, __ Int32Constant(2057));
    5462          16 :   value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(16)));
    5463          16 :   value = __ Word32And(value, __ Int32Constant(0x3FFFFFFF));
    5464          16 :   return value;
    5465             : }
    5466             : 
    5467          16 : Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
    5468             :     Node* node) {
    5469          16 :   Node* table = NodeProperties::GetValueInput(node, 0);
    5470          16 :   Node* key = NodeProperties::GetValueInput(node, 1);
    5471             : 
    5472             :   // Compute the integer hash code.
    5473          16 :   Node* hash = ChangeUint32ToUintPtr(ComputeUnseededHash(key));
    5474             : 
    5475          16 :   Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField(
    5476          32 :       AccessBuilder::ForOrderedHashMapOrSetNumberOfBuckets(), table));
    5477          16 :   hash = __ WordAnd(hash, __ IntSub(number_of_buckets, __ IntPtrConstant(1)));
    5478          16 :   Node* first_entry = ChangeSmiToIntPtr(__ Load(
    5479             :       MachineType::TaggedSigned(), table,
    5480             :       __ IntAdd(__ WordShl(hash, __ IntPtrConstant(kTaggedSizeLog2)),
    5481             :                 __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() -
    5482          16 :                                   kHeapObjectTag))));
    5483             : 
    5484          32 :   auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
    5485          32 :   auto done = __ MakeLabel(MachineType::PointerRepresentation());
    5486             :   __ Goto(&loop, first_entry);
    5487             :   __ Bind(&loop);
    5488             :   {
    5489             :     Node* entry = loop.PhiAt(0);
    5490             :     Node* check =
    5491          16 :         __ WordEqual(entry, __ IntPtrConstant(OrderedHashMap::kNotFound));
    5492          16 :     __ GotoIf(check, &done, entry);
    5493          16 :     entry = __ IntAdd(
    5494             :         __ IntMul(entry, __ IntPtrConstant(OrderedHashMap::kEntrySize)),
    5495          16 :         number_of_buckets);
    5496             : 
    5497          16 :     Node* candidate_key = __ Load(
    5498             :         MachineType::AnyTagged(), table,
    5499             :         __ IntAdd(__ WordShl(entry, __ IntPtrConstant(kTaggedSizeLog2)),
    5500             :                   __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() -
    5501          16 :                                     kHeapObjectTag)));
    5502             : 
    5503          16 :     auto if_match = __ MakeLabel();
    5504          16 :     auto if_notmatch = __ MakeLabel();
    5505          16 :     auto if_notsmi = __ MakeDeferredLabel();
    5506          16 :     __ GotoIfNot(ObjectIsSmi(candidate_key), &if_notsmi);
    5507          16 :     __ Branch(__ Word32Equal(ChangeSmiToInt32(candidate_key), key), &if_match,
    5508          16 :               &if_notmatch);
    5509             : 
    5510             :     __ Bind(&if_notsmi);
    5511          32 :     __ GotoIfNot(
    5512          32 :         __ WordEqual(__ LoadField(AccessBuilder::ForMap(), candidate_key),
    5513             :                      __ HeapNumberMapConstant()),
    5514          16 :         &if_notmatch);
    5515          32 :     __ Branch(__ Float64Equal(__ LoadField(AccessBuilder::ForHeapNumberValue(),
    5516             :                                            candidate_key),
    5517             :                               __ ChangeInt32ToFloat64(key)),
    5518          16 :               &if_match, &if_notmatch);
    5519             : 
    5520             :     __ Bind(&if_match);
    5521             :     __ Goto(&done, entry);
    5522             : 
    5523             :     __ Bind(&if_notmatch);
    5524             :     {
    5525          16 :       Node* next_entry = ChangeSmiToIntPtr(__ Load(
    5526             :           MachineType::TaggedSigned(), table,
    5527             :           __ IntAdd(
    5528             :               __ WordShl(entry, __ IntPtrConstant(kTaggedSizeLog2)),
    5529             :               __ IntPtrConstant(OrderedHashMap::HashTableStartOffset() +
    5530             :                                 OrderedHashMap::kChainOffset * kTaggedSize -
    5531          16 :                                 kHeapObjectTag))));
    5532             :       __ Goto(&loop, next_entry);
    5533             :     }
    5534             :   }
    5535             : 
    5536             :   __ Bind(&done);
    5537          16 :   return done.PhiAt(0);
    5538             : }
    5539             : 
    5540          13 : Node* EffectControlLinearizer::LowerDateNow(Node* node) {
    5541          13 :   Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
    5542             :   Runtime::FunctionId id = Runtime::kDateCurrentTime;
    5543          13 :   auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
    5544          13 :       graph()->zone(), id, 0, properties, CallDescriptor::kNoFlags);
    5545          13 :   return __ Call(call_descriptor, __ CEntryStubConstant(1),
    5546             :                  __ ExternalConstant(ExternalReference::Create(id)),
    5547          13 :                  __ Int32Constant(0), __ NoContextConstant());
    5548             : }
    5549             : 
    5550             : #undef __
    5551             : 
    5552           0 : Factory* EffectControlLinearizer::factory() const {
    5553           0 :   return isolate()->factory();
    5554             : }
    5555             : 
    5556           0 : Isolate* EffectControlLinearizer::isolate() const {
    5557           0 :   return jsgraph()->isolate();
    5558             : }
    5559             : 
    5560             : }  // namespace compiler
    5561             : }  // namespace internal
    5562      183054 : }  // namespace v8

Generated by: LCOV version 1.10