LCOV - code coverage report
Current view: top level - src/compiler - effect-control-linearizer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2057 2314 88.9 %
Date: 2019-04-17 Functions: 168 193 87.0 %

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

Generated by: LCOV version 1.10