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