LCOV - code coverage report
Current view: top level - src/compiler - effect-control-linearizer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2066 2280 90.6 %
Date: 2019-03-21 Functions: 167 186 89.8 %

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

Generated by: LCOV version 1.10