LCOV - code coverage report
Current view: top level - src/compiler - effect-control-linearizer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1857 2055 90.4 %
Date: 2019-02-19 Functions: 161 179 89.9 %

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

Generated by: LCOV version 1.10